0% found this document useful (0 votes)
27 views9 pages

Reporte

The document reports on exercises from Laboratory 7. Exercise 1 simulates heat diffusion using explicit finite differences and OpenMP for parallelization. Exercise 2 evaluates sorting algorithms, generating random arrays, measuring sequential and parallel times for bubblesort and odd-even sort using OpenMP. Analysis shows bubblesort has better scalability as its speedup increases with data size, while odd-even sort speedup deteriorates for larger problems with 4 threads.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views9 pages

Reporte

The document reports on exercises from Laboratory 7. Exercise 1 simulates heat diffusion using explicit finite differences and OpenMP for parallelization. Exercise 2 evaluates sorting algorithms, generating random arrays, measuring sequential and parallel times for bubblesort and odd-even sort using OpenMP. Analysis shows bubblesort has better scalability as its speedup increases with data size, while odd-even sort speedup deteriorates for larger problems with 4 threads.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

reporte

November 3, 2023

1 Laboratorio 7
1.1 Ejericicio 1
1.1.1 A
#include <iostream>
#include <cmath>
#include <ctime>
#include <omp.h> // Incluye la cabecera de OpenMP

double frontera(double x, double tiempo) {


double limite;
if (x < 0.5) limite = 100.0 + 10.0 * sin(tiempo);
else limite = 75.0;
return limite;
}

double inicial(double x, double tiempo) {


double limite;
limite = 95.0;
return limite;
}

int main(int argc, char *argv[]) {


int num_threads = 2;

if (argc > 1) {
num_threads = atoi(argv[1]);
}

std::cout << " num_threads: " << num_threads << std::endl;


omp_set_num_threads(num_threads);

int i, j, j_min = 0, j_max = 400, tag, n = 10;


double k = 0.002;
double tiempo, dt, tmax = 10.0, tmin = 0.0, tnew;
double u[n], unew[n], x[n], dx;
double x_max = 1.0, x_min = 0.0;

1
dt = (tmax - tmin) / (double)(j_max - j_min);
dx = (x_max - x_min) / (double)(n - 1);
x[0] = 0;
for (i = 1; i < n; i++) {
x[i] = x[i - 1] + dx;
}

// Inicialización
tiempo = tmin;
u[0] = 0.0;
for (i = 1; i <= n; i++) u[i] = inicial(x[i], tiempo);
u[n + 1] = 0.0;

// Valores de temperatura al siguiente intervalo de tiempo


for (j = 1; j <= j_max; j++) {
tnew += dt;

// Actualizar temperatura paralelamente


#pragma omp parallel for shared(u, unew)
for (i = 1; i <= n; i++) {
unew[i] = u[i] + (dt * k / dx / dx) * (u[i - 1] - 2.0 * u[i] + u[i + 1]);
}

// Aplicar condiciones de frontera


unew[1] = frontera(x[1], tnew);
unew[n] = frontera(x[n], tnew);

// Actualizar tiempo y temperatura


tiempo = tnew;

for (i = 1; i <= n; i++) {


u[i] = unew[i];
if (j == j_max) printf("%f %f %f\n", tiempo, x[i], u[i]);
}
}

return 0;
}

1.2 Ejercicio 2
1.2.1 A
#include <iostream>
#include <fstream>
#include <random>
#include <chrono>
#include <omp.h>

2
using namespace std;
#define LIMIT 1000000

void imprimir_array(int A[], int N);


void Sort(int A[], int N);
void Swap(int *X, int *Y);
void leer_array(int array[], int *limite, char *filename);
int numeros[LIMIT];
int size_ = LIMIT;
int num_threads = 4;

void generate_array(int array[], int *size)


{
int i;
random_device rd;
mt19937 gen(rd());

uniform_int_distribution<int> dis(0, 100);

for (i = 0; i < *size; i++)


{
int randomnumber = dis(gen);
array[i] = randomnumber;
}
}

int main(int argc, char *argv[])


{
// Leo parametros de size y num_threads
if (argc > 1)
{
size_ = atoi(argv[1]);
if (argc > 2)
num_threads = atoi(argv[2]);
}
cout << "size: " << size_ << " num_threads: " << num_threads << endl;
omp_set_num_threads(num_threads);

generate_array(numeros, &size_);
// se imprime el array
// imprimir_array(numeros, size_);
// se ordena el array
auto start_time = chrono::high_resolution_clock::now();
Sort(numeros, size_);
auto end_time = chrono::high_resolution_clock::now();

chrono::duration<double> elapse_time = end_time - start_time;

3
cout << "Elapse time: " << elapse_time.count() << " s\n";
// se imprime el array ordenado
// printf("\nArray ordenado:\n");
// imprimir_array(numeros, size_);
return 0;
}

void leer_array(int array[], int *size, char *filename)


{
int numero; // numero leido
int counter = 0; // counter for elems in file
ifstream opened;
opened.open(filename);
while (!opened.fail() && counter < *size)
{
// lee hasta EOF o muchos elementos
opened >> numero;
array[counter++] = numero; // dar valores al array
if (counter >= *size) // muchos numeros para el array
cout << "...muchos numeros para el array\n";
}
opened.close();
*size = --counter; // ajusta el tamaño
cout << *size << " numeros leidos" << endl;
}

void imprimir_array(int A[], int N)


{
int i;
cout << "[";
for (i = 0; i < N; i++)
cout << A[i] << " ";
cout << "]\n";
}

void Sort(int A[], int N)


{
int i, j;
#pragma omp parallel for default(none) shared(A, N) private(i, j)
for (i = 0; i < N - 1; i++)
{
for (j = 0; j < N - i - 1; j++)
{
if (A[j] > A[j + 1])
{
Swap(&A[j], &A[j + 1]);
}
}

4
}
}

void Swap(int *X, int *Y)


{
int temp = *X;
*X = *Y;
*Y = temp;
}
[7]: import matplotlib.pyplot as plt

n = [100, 500, 1000, 1500, 50000, 100000]


t_sequential = [2.3304e-05, 0.000504612, 0.00195427, 0.00485431, 7.02844, 28.
↪6668]

t_4_threads = [0.000237325, 0.00184459, 0.00111098, 0.00231326, 2.68199, 10.


↪6033]

t_8_threads = [0.00010539, 0.000479905, 0.0019533, 0.00505518, 7.01886, 29.5551]


t_12_threads = [2.3394e-05, 0.000611882, 0.00477099, 0.0047245, 7.0099, 29.5369]

# HAcemos grafica del speedup para cada medicion con n threads


#plt.plot(n, t_sequential, label='Sequential', marker='o')
plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_4_threads)],␣
↪label='4 Threads', marker='x')

plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_8_threads)],␣


↪label='8 Threads', marker='s')

plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_12_threads)],␣


↪label='12 Threads', marker='*')

plt.legend()
plt.xlabel('n')
plt.ylabel('Tiempo (s)')
plt.title('Speedup')

plt.show()

5
1.2.2 B
#include <iostream>
#include <vector>
#include <random>
#include <chrono>
#include <omp.h>

void generate_array(int array[], int *size)


{
int i;
std::random_device rd;
std::mt19937 gen(rd());

std::uniform_int_distribution<int> dis(0, 100);

for (i = 0; i < *size; i++)


{
int randomnumber = dis(gen);
array[i] = randomnumber;

6
}
}

void oddEvenSort(int arr[], int n) {


bool sorted = false;

while (!sorted) {
sorted = true;

// Fase par (odd)


#pragma omp parallel for shared(arr, sorted)
for (int i = 1; i <= n - 2; i += 2) {
if (arr[i] > arr[i + 1]) {
std::swap(arr[i], arr[i + 1]);
sorted = false;
}
}

// Fase impar (even)


#pragma omp parallel for shared(arr, sorted)
for (int i = 0; i <= n - 2; i += 2) {
if (arr[i] > arr[i + 1]) {
std::swap(arr[i], arr[i + 1]);
sorted = false;
}
}
}
}

int main(int argc, char* argv[]) {


// Leo parametros de size y num_threads
int LIMIT = 1000;
int num_threads = 2;

if (argc > 1) {
LIMIT = atoi(argv[1]);
if (argc > 2)
num_threads = atoi(argv[2]);
}

std::cout << "size: " << LIMIT << " num_threads: " << num_threads << std::endl;
omp_set_num_threads(num_threads);

int numbers[LIMIT];
generate_array(numbers, &LIMIT);

// std::cout << "Arreglo original: ";


// for (int i = 0; i < LIMIT; i++) {

7
// std::cout << numbers[i] << " ";
// }
// std::cout << "\n";

auto start_time = std::chrono::high_resolution_clock::now();


oddEvenSort(numbers, LIMIT);
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapse_time = end_time - start_time;
std::cout << "Elapse time: " << elapse_time.count() << " s\n";

// std::cout << "Arreglo ordenado: ";


// for (int i = 0; i < LIMIT; i++) {
// std::cout << numbers[i] << " ";
// }
// std::cout << "\n";

return 0;
}
[8]: import matplotlib.pyplot as plt

n = [100, 500, 1000, 1500, 50000, 100000]


t_sequential = [0.000140226,0.00112799, 0.0036593, 0.00775875, 8.37909, 34.425]
t_4_threads = [0.000262959, 0.00130827, 0.00497814, 0.00918952, 12.195, 45.9775]
t_8_threads = [0.000476351, 0.00708497, 0.00843195, 0.00883867, 9.16787, 34.
↪4995]

t_12_threads = [0.00505474, 0.0222055, 0.0408817, 0.0591501, 9.91938, 35.3585]

# HAcemos grafica del speedup para cada medicion con n threads


#plt.plot(n, t_sequential, label='Sequential', marker='o')
plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_4_threads)],␣
↪label='4 Threads', marker='x')

plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_8_threads)],␣


↪label='8 Threads', marker='s')

plt.plot(n, [seq / par for seq, par in zip(t_sequential, t_12_threads)],␣


↪label='12 Threads', marker='*')

plt.legend()
plt.xlabel('n')
plt.ylabel('Tiempo (s)')
plt.title('Speedup')

plt.show()

8
1.2.3 C
Teniendo en cuenta las gráficas el algoritmo bubblesort es más escalable que el algoritmo par-impar.
Debido a que el comportamiento, dada la experimentación siempre tenderá a subir. En cambio, el
speedup del algoritmo par-impar para 4 threads tiene un deterioro del speedup cuando aumenta la
cantidad de datos.

You might also like