Informe 2

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

informe2

October 25, 2023

0.1 Ejercicio 2
0.1.1 A

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <omp.h>

using namespace std;

void suma_de_prefijos(int *A, int n)


{
int i;
for (i = 1; i < n; i++)
A[i] += A[i - 1];
}

void scan_left(int *C, int n)


{
int i;
for (i = 1; i < n; i++)
C[i] += C[i - 1];
}

void quicksort(int *B, int n)


{
int i, j;
int x, t;
if (n < 2)
return;
x = B[n / 2];
for (i = 0, j = n - 1;; i++, j--)
{
while (B[i] < x)
i++;
while (x < B[j])

1
j--;
if (i >= j)
break;
t = B[i];
B[i] = B[j];
B[j] = t;
}
quicksort(B, i);
quicksort(B + i, n - i);
}

void print_arrays(int *A, int *B, int *C, int n)


{
for (int i = 0; i < n; ++i)
{
std::cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << B[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << C[i] << " ";
}
cout << endl;
}

int x = 1;

int OpArr(int *A, int *B, int *C, int n)


{
int i, j;
int s1, s2, a, res;

#pragma omp task depend(out : A[0], B[0], C[0])


{
suma_de_prefijos(A, n); // obtiene el array de suma de prefijos de A
// cout << "Prefix sum" << endl;
// print_arrays(A, B, C, n);
}

quicksort((int *)B, n); // ordena el array B


// cout << "Arrays sorted: " << endl;
// print_arrays(A, B, C, n);

2
scan_left(C + x, n); // acumula los valores de elementos de C mas
// cout << "Scan left" << endl;
// print_arrays(A, B, C, n);

for (i = 0; i < n; i++)


{ /* primer bucle for */
s1 = 0;
for (j = 0; j < n; j++)
s1 += A[j] * B[j];
for (j = 0; j < n; j++)
A[j] *= s1;
}

for (i = 0; i < n; i++)


{ /* segundo bucle for */
s2 = 0;
for (j = 0; j < n; j++)
s2 += B[j] * C[j];
for (j = 0; j < n; j++)
C[j] *= s2;
}
/* calculo final */
a = 0.0;
if (s2 != 0)
{
a = static_cast<double>(s1) / s2;
}
res = 0;

for (i = 0; i < n; i++)


res += a * C[i];

return res;
}

int main()
{
int n = 100000;
int A[n], B[n], C[n];

srand(time(NULL));
for (int i = 0; i < n; ++i)
{
A[i] = rand() % 10;
}

3
for (int i = 0; i < n; ++i)
{
B[i] = rand() % 10;
}

for (int i = 0; i < n; ++i)


{
C[i] = rand() % 10;
}

// cout << "Initial arrays: " << endl;


// print_arrays(A, B, C, n);
// cout << endl;

cout << OpArr(A, B, C, n) << endl;

double time = end - start;


cout << "Time: " << time << endl;
// print_arrays((int *)A, (int *)B, (int *)C, n);
}#include <iostream>
#include <cstdlib>
#include <ctime>
#include <omp.h>

using namespace std;

void suma_de_prefijos(int *A, int n)


{
int i;
for (i = 1; i < n; i++)
A[i] += A[i - 1];
}

void scan_left(int *C, int n)


{
int i;
for (i = 1; i < n; i++)
C[i] += C[i - 1];
}

void quicksort(int *B, int n)


{
int i, j;
int x, t;
if (n < 2)
return;

4
x = B[n / 2];
for (i = 0, j = n - 1;; i++, j--)
{
while (B[i] < x)
i++;
while (x < B[j])
j--;
if (i >= j)
break;
t = B[i];
B[i] = B[j];
B[j] = t;
}
quicksort(B, i);
quicksort(B + i, n - i);
}

void print_arrays(int *A, int *B, int *C, int n)


{
for (int i = 0; i < n; ++i)
{
std::cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << B[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << C[i] << " ";
}
cout << endl;
}

int x = 1;

int OpArr(int *A, int *B, int *C, int n)


{
int i, j;
int s1, s2, a, res;

#pragma omp task depend(out : A[0], B[0], C[0])


{
suma_de_prefijos(A, n); // obtiene el array de suma de prefijos de A
// cout << "Prefix sum" << endl;
// print_arrays(A, B, C, n);

5
}

quicksort((int *)B, n); // ordena el array B


// cout << "Arrays sorted: " << endl;
// print_arrays(A, B, C, n);

scan_left(C + x, n); // acumula los valores de elementos de C mas


// cout << "Scan left" << endl;
// print_arrays(A, B, C, n);

for (i = 0; i < n; i++)


{ /* primer bucle for */
s1 = 0;
for (j = 0; j < n; j++)
s1 += A[j] * B[j];
for (j = 0; j < n; j++)
A[j] *= s1;
}

for (i = 0; i < n; i++)


{ /* segundo bucle for */
s2 = 0;
for (j = 0; j < n; j++)
s2 += B[j] * C[j];
for (j = 0; j < n; j++)
C[j] *= s2;
}
/* calculo final */
a = 0.0;
if (s2 != 0)
{
a = static_cast<double>(s1) / s2;
}
res = 0;

for (i = 0; i < n; i++)


res += a * C[i];

return res;
}

int main()
{
int n = 100000;
int A[n], B[n], C[n];

6
srand(time(NULL));
for (int i = 0; i < n; ++i)
{
A[i] = rand() % 10;
}

for (int i = 0; i < n; ++i)


{
B[i] = rand() % 10;
}

for (int i = 0; i < n; ++i)


{
C[i] = rand() % 10;
}

// cout << "Initial arrays: " << endl;


// print_arrays(A, B, C, n);
// cout << endl;

cout << OpArr(A, B, C, n) << endl;

double time = end - start;


cout << "Time: " << time << endl;
// print_arrays((int *)A, (int *)B, (int *)C, n);
}

7
0.1.2 DAG

0.2 B
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <omp.h>

using namespace std;

void suma_de_prefijos(int *A, int n)


{
int i;
for (i = 1; i < n; i++)
A[i] += A[i - 1];
}

void scan_left(int *C, int n)


{
int i;
for (i = 1; i < n; i++)
C[i] += C[i - 1];
}

void quicksort(int *B, int n)

8
{
int i, j;
int x, t;
if (n < 2)
return;
x = B[n / 2];
for (i = 0, j = n - 1;; i++, j--)
{
while (B[i] < x)
i++;
while (x < B[j])
j--;
if (i >= j)
break;
t = B[i];
B[i] = B[j];
B[j] = t;
}
quicksort(B, i);
quicksort(B + i, n - i);
}

void print_arrays(int *A, int *B, int *C, int n)


{
for (int i = 0; i < n; ++i)
{
std::cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << B[i] << " ";
}
cout << endl;
for (int i = 0; i < n; ++i)
{
std::cout << C[i] << " ";
}
cout << endl;
}

int x = 1;

int OpArr(int *A, int *B, int *C, int n)


{
int i, j;
int s1, s2, a, res;

9
#pragma omp task depend(out : A[0], B[0], C[0])
{
suma_de_prefijos(A, n); // obtiene el array de suma de prefijos de A
// cout << "Prefix sum" << endl;
// print_arrays(A, B, C, n);
}

#pragma omp task depend(in : A[0]) depend(out : B[0])


{
quicksort((int *)B, n); // ordena el array B
// cout << "Arrays sorted: " << endl;
// print_arrays(A, B, C, n);
}
#pragma omp task depend(in : C[x]) depend(out : C[0])
{
scan_left(C + x, n); // acumula los valores de elementos de C mas
// cout << "Scan left" << endl;
// print_arrays(A, B, C, n);
}

#pragma omp taskwait

#pragma omp parallel for reduction(+ : s1, s2) private(i, j)


for (i = 0; i < n; i++)
{ /* primer bucle for */
s1 = 0;
for (j = 0; j < n; j++)
s1 += A[j] * B[j];
for (j = 0; j < n; j++)
A[j] *= s1;
}

#pragma omp parallel for private(i)


for (i = 0; i < n; i++)
{ /* segundo bucle for */
s2 = 0;
for (j = 0; j < n; j++)
s2 += B[j] * C[j];
for (j = 0; j < n; j++)
C[j] *= s2;
}
/* calculo final */
a = 0.0;
if (s2 != 0)
{
a = static_cast<double>(s1) / s2;
}
res = 0;

10
#pragma omp parallel for reduction(+ : res) private(i)
for (i = 0; i < n; i++)
res += a * C[i];

return res;
}

int main()
{
int n = 100000;
int A[n], B[n], C[n];

srand(time(NULL));
for (int i = 0; i < n; ++i)
{
A[i] = rand() % 10;
}

for (int i = 0; i < n; ++i)


{
B[i] = rand() % 10;
}

for (int i = 0; i < n; ++i)


{
C[i] = rand() % 10;
}

// cout << "Initial arrays: " << endl;


// print_arrays(A, B, C, n);
// cout << endl;

omp_set_num_threads(64);
double start, end;

start = omp_get_wtime();
#pragma omp parallel
{
#pragma omp single
{
cout << OpArr(A, B, C, n) << endl;
}
}
end = omp_get_wtime();

double time = end - start;


cout << "Time: " << time << endl;

11
// print_arrays((int *)A, (int *)B, (int *)C, n);
}

0.2.1 C
[5]: import matplotlib.pyplot as plt
import math

n = 1000000
times_ = []
ps= [1, 2, 4, 8, 16, 32]
for p in ps:
times_.append(n* math.log(n) / p)

times = [92.4054, 90.5576, 90.0058, 90.5586, 89.6966, 89.883]

plt.plot(ps, times, label="tiempo experimental", marker="o")


plt.plot(ps, times_, label="tiempo teorico", marker="x")

plt.xlabel("# procesadores")
plt.ylabel("tiempo (s)")
plt.legend()
plt.show()

12
[3]: import numpy as np
import matplotlib.pyplot as plt

p_values = [1, 2, 4, 8, 16, 32] # Personaliza esto según tus necesidades

experimental_times = [92.4054, 90.5576, 90.0058, 90.5586, 89.6966, 89.883]

n = 1000000 # Ajusta esto según tu tamaño de problema

theoretical_time = [(n * np.log(n)) / p for p in p_values]

speedup_experimental = [experimental_times[0] / t for t in experimental_times]

speedup_theoretical = [experimental_times[0] / t for t in theoretical_time]

# Grafica el speedup experimental y teórico


plt.figure(figsize=(10, 6))
plt.plot(p_values, speedup_experimental, marker='o', label='Speedup␣
↪Experimental')

plt.plot(p_values, speedup_theoretical, marker='x', label='Speedup Teórico')

13
plt.xlabel('Número de Hilos (p)')
plt.ylabel('Speedup')
plt.title('Speedup vs. Número de Hilos')
plt.legend()
plt.grid(True)
plt.show()

[6]: def algorithm_complexity(n):


return n * np.log(n)

def sequential_time(n):
return algorithm_complexity(n)

def theoretical_time(n, p):


return algorithm_complexity(n) / p

def theoretical_speedup(n, p):


return sequential_time(n) / theoretical_time(n, p)

n = 1000000
p_values = [1, 2, 4, 8, 16, 32] # Números de hilos a evaluar

# Calcular y mostrar el speedup teórico para diferentes valores de p


for p in p_values:

14
speedup = theoretical_speedup(n, p)
print(f"Speedup teórico para p = {p}: {speedup:.2f}")

Speedup teórico para p = 1: 1.00


Speedup teórico para p = 2: 2.00
Speedup teórico para p = 4: 4.00
Speedup teórico para p = 8: 8.00
Speedup teórico para p = 16: 16.00
Speedup teórico para p = 32: 32.00

15

You might also like