2014-06-18 69 views
0

我有視覺工作室,其中OPENMP 3.0未支載(這意味着它不具有任務構建體)的問題是一個線程具有產生多組數據,而另一個線程的陣列的必須爲每個完成的集合處理這些數據...有沒有使用任務的任何解決方法?如能得到任何幫助,我將不勝感激。驗證碼:執行與相關的數據任務級並行

int id = omp_get_thread_num(); 
    if (id == 0) 
    { 
     for (int k = 0; k < n; k++) 
     { 
      int f = k * r * c; 
      for (int i = 0; i < r; i++) 
      { 
       int rw = i * c; 
       for (int j = 0; j < c; j++) 
       { 
        p[f + rw + j] = rand() % 65535; 
       } 
      } 
      _sleep(500); 
     } 
    } 
    if (id == 1) 
    { 
     _sleep(200); 
     for (int k = 0; k < n; k++) 
     { 
      int f = k * r* c; 
      cout << "\n" << k; 
      for (int i = 0; i < r; i++) 
      { 
       int rw = i * c; 
       for (int j = 0; j < c; j++) 
       { 
        p[f + rw + j] *= sin(2 * 3.14 * (10.0/100.0) * k); 
       } 
      } 
      Mat img(r, c, CV_16UC1, p); 
      namedWindow("output", CV_WINDOW_AUTOSIZE); 
      imshow("output", img); 
      waitKey(); 
     } 
    } 
} 
system("pause"); 

這個程序的工作,但我不知道是否是並行或串行跑步或做任何冗餘時...

+0

您可以打印線程ID並檢查是否有不同的ID。 – nwp

+0

有一個沉重的依賴btw。線程0,其中容器中填充了隨機數和線程1,其中使用這些隨機數進行計算。你如何確保隨機數能夠及時獲得,特別是如果第一個線程較慢或被調度程序暫停? – Christophe

回答

2

是的,有標準的C++ 11個線程,但需要一些工作。

使用代碼的線程/基本結構:

我asume你是using namespace std;。另外你需要:

#include <thread> 
#include <chrono> 

訣竅是把你的線程代碼在void函數接受作爲輸入你的線程ID,以及共享變量(如附圖)。舉例來說,我用這一個快速的可行性測試(你必須微調/調整類型的/ etc ...):

void mytask (int id, int&n, int& r, int& c, double *p) 
{ 
    if (id == 0) 
    { ... } 
    if (id == 1) 
    { ... } 
} 

您還可以使用正確的睡眠功能代替你前一個:

this_thread::sleep_for (std::chrono::milliseconds(500)); //_sleep (500); 

然後在你的代碼,你可能會啓動你的線程,已宣佈後初始化共享變量:

... 
thread t1 (mytask, 0, n, r, c, p); // create an launch threads 
thread t2 (mytask, 1, n, r, c ,p); // 

t1.join(); // wait for t1 to finish 
t2.join(); // wait for t2 to finish 
... 

這對基本概念。它適用於沒有openMP的VC2013 Express,至少對於這個概念。

共享數據和同步:

現在你也有微調,並檢查是否有在同一個變量的兩個線程之間的競爭,也可以使用或串行訪問。

算法分析表明,第一個線程將隨機數放在一個表中,第二個線程對這些結果應用公式。這假定第一個線程總是在第二個線程使用它們之前計算元素。但是,您不能過多地假設線程的調度。系統可能會放慢速度,甚至凍結其中一個並在稍後恢復。

所以這裏的最初的想法(但還需要進一步ellaboration),使用:

#include <atomic> 

定義共享保護的變量,將存儲外環計數器(我在這裏建議這一點,因爲這兩個線程訪問P []使用相同的序列):

atomic<int> line_ready=-1; // U used here a global variable 

在生產線中,添加在所述外環的端部的線:

line_ready.store (k); // sync: loop was processed from 0 to k. 

在消費線,添加在外部循環的開始行:

while (k>line_ready.load()) // sync: read k to know if we have to wait for data 
this_thread::sleep_for (std::chrono::milliseconds(100)); // wait 

這將等待數據,如果它是不可用的。現在取決於你了!

+0

這將導致競爭條件,因爲t1和t2將同時寫入相同的數組。如果你在t2之後啓動t2,那麼你已經有效地進行了串行操作,否定了多線程的目的。 –

+0

@Z boson:原來的openMP程序是否受到相同的競爭條件?我的印象是_sleep()指令是一個嘗試在表格元素級別克服競速。 – Christophe

+0

是的,原來的OpenMP程序受到相同的競爭條件。 OP需要用他真正在做的事情來更新他的問題。無論如何,我會給你+1,因爲你教會了我關於C++的東西(我不再使用太多東西)。 –