2015-11-10 57 views
1

我有一個問題和一個問題。 我試圖用omp做一些矩陣乘法運算。使用omp生成矩陣會導致麻煩,不同的柱面

如果我使用多個線程創建矩陣a,b和c,則列的大小不相等。 即使我使用關鍵push_back,問題仍然存在。 我以爲omp將for循環分成了大小相等的部分,所以每個線程都應該有自己的列。問題在哪裏?

什麼是給每個線程一個向量的好方法? 在沒有關鍵和原子的情況下避免共享內存問題的方法是什麼?如果我生成的數據,並希望將它保存在某個地方。 謝謝。 P.S.我正在學習英語。它離完美很遠,所以請不要介意。

#include "stdafx.h" 
#include <omp.h> 
#include <iostream> 
#include <ctime> 
#include <vector> 

#define NRA 300    /* number of rows in matrix A */ 
#define NCA 300    /* number of columns in matrix A */ 
#define NCB 300     /* number of columns in matrix B */ 

int main(int argc, char *argv[]) 
{ 
    int i, j, k, chunk; 

    std::vector < std::vector<int> > a; 
    a.resize(NRA); 
    std::vector < std::vector<int> > b; 
    b.resize(NCA); 
    std::vector < std::vector<int> > c; 
    c.resize(NRA); 
    /* 
    double a[NRA][NCA]; 
    double b[NCA][NCB]; 
    double c[NRA][NCB]; 
    */ 
    chunk = 10;      

    std::clock_t start;   //Zeitmessung 
    double duration;   //Zeitdauer der Parallelisierung 


     omp_set_num_threads(4); 
#pragma omp parallel 
     { 
#pragma omp for schedule (static, chunk) 
      for (i = 0; i < NRA; i++) 
       for (j = 0; j < NCA; j++) 
        a[i].push_back(i + j); 
#pragma omp for schedule (static, chunk) 
      for (i = 0; i < NCA; i++) 
       for (j = 0; j < NCB; j++) 
        b[i].push_back(i*j); 
#pragma omp for ordered schedule(static, chunk) 
      for (i = 0; i < NRA; i++) 
       for (j = 0; j < NCB; j++) 
        c[i].push_back(0); 
     } 

    for (int nthreads = 1; nthreads < 40; nthreads++) 
    { 
     start = std::clock(); 
     omp_set_dynamic(0); 
#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,j,k) num_threads(nthreads) 
    { 

#pragma omp for schedule (static, chunk) 
     for (i = 0; i < NRA; i++) 
      for (j = 0; j < NCB; j++) 
       c[i][j] = 0; 

#pragma omp for ordered schedule (static, chunk) 
     for (i = 0; i < NRA; i++) 
     { 
      for (j = 0; j < NCB; j++) 
       for (k = 0; k < NCA; k++) 
        c[i][j] += a[i][k] * b[k][j]; 
     } 
    } 

     duration = (std::clock() - start)/(double)CLOCKS_PER_SEC; 
     //Time n threads need 
     std::cout << "Benoetigte Zeit fuer " << nthreads << " Threads betrug " << duration << " Sekunden." << std::endl; 
    } 

    std::cin.get(); 

} 
+1

'push_back()'絕對修改向量的元數據,特別是大小。我嘗試像調整外部元素('a','b','c')一樣調整內部向量的大小,然後修改元素('a [i] = i + j;平行運行等)。 – Melebius

+0

謝謝!有用。矢量矢量是存儲每個線程數據的好方法嗎? – Mehno

回答

0

push_back()絕對修改向量的元數據,尤其是大小。嘗試resize()內部載體像你一樣用外部的(a,b,c),然後在平行運行中修改元素(a[i] = i + j;等)。

由於您知道最初元素的最終數量,因此您可以使用普通數組而不是矢量來最小化開銷。

int a[NRA][NCA]; 
int b[NCA][NCB]; 
int c[NRA][NCB]; 

我想知道爲什麼你已經註釋掉了代碼的類似部分。 ;-)

+0

因爲我在玩omp。 ^^ 學習新東西。我學到了新的東西。不管怎麼說,謝謝 – Mehno

+0

我知道我的內在向量很大。如果我不知道他們的長度,我該怎麼辦? – Mehno

+0

使用矢量並調整它們的大小。調整大小必須發生在關鍵部分,因此只有一個線程可以隨時修改矢量元數據。出於性能原因,你應該喜歡一次調整大一點的部分('push_back()'一次只能添加一個元素)。或者每個矢量可以有一個線程,因此它們將獨立運行。 – Melebius