2013-05-23 9 views
0

что не так с моим кодом openMP? она всегда принимает только один поток и работает в то же время, как не-параллельной версииC++ openMP параллельное умножение матрицы

template <typename T> 
Matrix<T>* Matrix<T>::OMPMultiplication(Matrix<T>* A, Matrix<T>* B){ 

    if(A->ySize != B->xSize) 
     throw; 

    Matrix<T>* C = new Matrix<T>(A->xSize, B->ySize); 

    sizeType i, j, k; 
    T element; 

    #pragma omp parallel for private(i, j) 
    { 
     #pragma omp for private(i, j) 
     for(i = 0; i < A->xSize; i++) 
      cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 

      for(j = 0; j < B->ySize; j++){ 

       C->matrix[i][j] = 0; 
       for(k = 0; k < A->ySize; k++){ 
        C->matrix[i][j] += A->matrix[i][k] * B->matrix[k][j]; 
       } 

     } 
    } 
    return C; 
} 
+0

Первый прагма содержит «для», но это не 'for' Прагма (который является вторым один). – Pixelchemist

+0

@VictorSand Комбинация '#pragma omp parallel' с' #pragma omp for' не является вложенным параллелизмом. – Pixelchemist

ответ

1

Прежде всего, вам не хватает какой-то {} для i цикла и переменной k должна быть частной каждой итерации i петля. Однако, я думаю, вы также перепутали, как сочетаются прайсы parallel и for. Чтобы успешно распараллелить цикл for, вам нужно поместить его в прагму parallel, а затем в прагму for. Для этого вы можете либо изменить свой код в

#pragma omp parallel private(i, j, k) 
{ 
    #pragma omp for 
    for(i = 0; i < A->xSize; i++) { 
     cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl; 

     for(j = 0; j < B->ySize; j++) { 

      C->matrix[i][j] = 0; 
      for(k = 0; k < A->ySize; k++){ 
       C->matrix[i][j] += A->matrix[i][k] * B->matrix[k][j]; 
      } 

     } 
    } 
} 

или использовать в сочетании parallel for нотации

#pragma omp parallel for private(i, j, k) 
for(i = 0; i < A->xSize; i++) { 
    ... 
} 

Кроме того, убедитесь, что вы говорите OpenMP, чтобы использовать более 1 нить здесь. Это можно сделать как с omp_set_num_threads(<number of threads here>), так и путем установки переменных окружения, таких как OMP_NUM_THREADS.

Надеюсь, вы разобьете его. :)

1

я получаю немного быстрее результат с моими 4 ядра, используя этот код:

omp_set_num_threads(4); 
    #pragma omp parallel for 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      c[i] += b[j] * a[j][i]; 
     } 
    } 

Полная программа

#include <stdio.h> 
#include <time.h> 
#include <omp.h> 
#include <stdlib.h> 


int main() { 
    int i, j, n, a[719][719], b[719], c[719]; 

    clock_t start = clock(); 

    n = 100; //Max 719 

    printf("Matrix A\n"); 

    for (i = 0; i < n; ++i) { 
     for (j = 0; j < n; ++j) { 
      a[i][j] = 10; 
      printf("%d ", a[i][j]); 
     } 
     printf("\n"); 
    } 

    printf("\nMatrix B\n"); 

#pragma omp parallel private(i) shared(b) 
    { 
#pragma omp for 
     for (i = 0; i < n; ++i) { 
      b[i] = 5; 
      printf("%d\n", b[i]); 
     } 
    } 

    printf("\nA * B\n"); 

#pragma omp parallel private(i) shared(c) 
    { 
#pragma omp for 
     for (i = 0; i < n; ++i) { 
      c[i] = 0; 
     } 
    } 

#pragma omp parallel private(i,j) shared(n,a,b,c) 
    { 
#pragma omp for schedule(dynamic) 
     for (i = 0; i < n; ++i) { 
      for (j = 0; j < n; ++j) { 
       c[i] += b[j] * a[j][i]; 
      } 
     } 
    } 


#pragma omp parallel private(i) shared(c) 
    { 
#pragma omp for 
     for (i = 0; i < n; ++i) { 
      printf("%d\n", c[i]); 
     } 
    } 

    clock_t stop = clock(); 
    double elapsed = (double) (stop - start)/CLOCKS_PER_SEC; 
    printf("\nTime elapsed: %.5f\n", elapsed); 
    start = clock(); 
    printf("Matrix A\n"); 

    for (i = 0; i < n; ++i) { 
     for (j = 0; j < n; ++j) { 
      a[i][j] = 10; 
      printf("%d ", a[i][j]); 
     } 
     printf("\n"); 
    } 

    printf("\nMatrix B\n"); 

#pragma omp parallel private(i) shared(b) 
    { 
#pragma omp for 
     for (i = 0; i < n; ++i) { 
      b[i] = 5; 
      printf("%d\n", b[i]); 
     } 
    } 
    printf("\nA * B\n"); 
    omp_set_num_threads(4); 
#pragma omp parallel for 
    for (i = 0; i < n; i++) { 
     for (j = 0; j < n; j++) { 
      c[i] += b[j] * a[j][i]; 
     } 
    } 
    stop = clock(); 
    elapsed = (double) (stop - start)/CLOCKS_PER_SEC; 
    printf("\nTime elapsed: %.5f\n", elapsed); 
    return 0; 
} 

Первый метод принимает

Время истекло: 0,03442

Второй метод

Время истекло: 0,02630

Смежные вопросы