Obsah

Cvičení 6

1.

Bez záruky, ale zdá se, že funguje…

#include <stdio.h>
#include <omp.h>
 
int main (int argc, char* argv[]) {
	int A[4][6] = {{1, 2, 3, 1, 2, 3}, {4, 5, 6, 4, 5, 6}, {1, 2, 3, 1, 2, 3}, {4, 5, 6, 4, 5, 6}};
	int B[6][4] = {{1, 2, 1, 2}, {3, 4, 3, 4}, {5, 6, 5, 6}, {1, 2, 1, 2}, {3, 4, 3, 4}, {5, 6, 5, 6}};
 
	int Ar = sizeof(A) / sizeof(A[0]); // A rows
	int Ac = sizeof(A[0]) / sizeof(A[0][0]); // A cols
 
	int Br = sizeof(B) / sizeof(B[0]); // B rows
	int Bc = sizeof(B[0]) / sizeof(B[0][0]); // B cols
 
	int C[Ar][Bc];
 
	int Cr = Ar;
	int Cc = Bc;
 
	int x, y;
	for (x = 0; x < Cr; x++) {
		for (y = 0; y < Cc; y++) {
			C[x][y] = 0;
		}
	}
 
	int i, j, k;
	#pragma omp parallel for private(i, j, k) shared(C) num_threads(4)
	for(i = 0; i < Ar; i++) {
		for( j = 0; j < Bc; j++) {
			for( k = 0; k < Ac; k++) { // or Br
				C[i][j] += A[i][k] * B[k][j];
			}
		}
	}
 
	printf("A radky %d, sloupce %d\nB radky %d, sloupce %d\nC radky %d, sloupce %d\n", Ar, Ac, Br, Bc, Cr, Cc);
 
	printf("\nMatice C:\n");
	for(i = 0; i < Cr; i++) {
		for( k = 0; k < Cc; k++) { // or Br
			printf("%d ", C[i][k]);
		}
		printf("\n");
	}
 
	return 0;
}

2.

#include <stdio.h>
#include <omp.h>
#include <cmath>
 
double f(double x, double R) {
    if (x < 2 * R) {
        return 0.5 * (-cos(M_PI * x / R) + 1);
    }
    return 0.0;
}
 
int main(int argc, char* argv[]) {
    double g1 = 0.0, g2 = 0.0, L = 0.1, R = 0.02, c = 1.5e8;
    const int pocetX = 100, pocetT = 1000;
    double dx = L / pocetX;
    double dt = 0.9 * sqrt((dx * dx) / (c * c));
    double **pole = NULL;
    pole = new double*[pocetX + 1];
    int i;
    for (i = 0; i < pocetX + 1; i++) {
        pole[i] = new double[pocetT + 1];
    }
    int pp = omp_get_num_procs();
    //pp=1;
    double konst = -0.5 * c * dt / dx;
    double start_time, run_time;
    start_time = omp_get_wtime();
#pragma omp parallel shared(pole, g1, g2, dx, dt, R, konst) private(i) num_threads(pp)
    {
#pragma omp for nowait
        for (i = 0; i < pocetT + 1; i++) {
            // levá a pravá okrajová podmínka
            pole[0][i] = g1;
            pole[pocetX][i] = g2;
        }
#pragma omp for
        for (i = 1; i < pocetX; i++) {
            // první řádek
            pole[i][0] = f(dx*i, R);
        }
#pragma omp for nowait
        for (i = 1; i < pocetX; i++) {
            // druhý řádek, možnost 2 ze cvičení
            pole[i][1] = pole[i][0] + konst * (pole[i + 1][0] - pole[i - 1][0]);
        }
    }
    konst = (c * c * dt * dt) / (dx * dx);
    for (int j = 2; j < pocetT + 1; j++) {
// první for nelze paralelizovat, hodnoty řádku jsou závislé na přechozích 2 řádcích
#pragma omp parallel for shared(pole, konst, j) private(i) num_threads(pp)
        for (i = 1; i < pocetX; i++) {
            // diskretizovaná dif. rovnice
            pole[i][j] = konst * (pole[i + 1][j - 1] - 2 * pole[i][j - 1] + pole[i - 1][j - 1]) + 2 * pole[i][j - 1] - pole[i][j - 2];
        }
    }
    run_time = omp_get_wtime() - start_time;
    // výstup pro Copy-Paste do MatLabu
    printf("X = [");
    for (int j = 0; j < pocetT + 1; j++) {
        for (i = 0; i < pocetX + 1; i++) {
            printf("%f ", pole[i][j]);
        }
        printf(";\n");
    }
    printf("];\n");
 
    printf(" Beh sledovane casti programu trval: %f s", run_time);
}