2016-02-26 70 views
1

我想使用線程運行同時在向量中檢查多個圖像。這裏是代碼在循環中提升Thread_Group速度非常慢

 boost::thread_group tGroup; 
     for (int line = 0;line < sourceImageData.size(); line++) { 
      for (int pixel = 0;pixel < sourceImageData[line].size();pixel++) { 
       for (int im = 0;im < m_images.size();im++) { 
        tGroup.create_thread(boost::bind(&ClassX::ClassXFunction, this, line, pixel, im)); 
       } 
       tGroup.join_all(); 
      } 
     } 

這創建了線程組,並通過像素數據行,然後循環每個像素,然後多個圖像。它是一個奇怪的項目,但無論如何,我將線程綁定到該代碼所在類的同一實例中的一個方法,因此使用「this」。它貫穿了大約20個圖像,在每個線程結束時進行綁定,然後在完成循環時,join_all函數在線程完成時生效。然後它進入下一個像素並重新開始。

心中已經測試運行在同一時間50個線程與這個簡單的程序

void run(int index) { 
    for (int i = 0;i < 100;i++) { 
     std::cout << "Index : " <<index<<" "<<i << std::endl; 
    } 
} 

int main() { 
    boost::thread_group tGroup; 

    for (int i = 0;i < 50;i++){ 
     tGroup.create_thread(boost::bind(run, i)); 
    } 

    tGroup.join_all(); 
    int done; 
    std::cin >> done; 
    return 0; 
} 

這工作得非常快。即使線程在前一個程序中綁定的方法比較複雜,它不應該像現在這樣慢。一個循環的sourceImageData(行)需要4秒鐘才能完成。我是新來提高線程,所以我不知道是否是嵌套循環或其他方面的公然錯誤。任何見解都會被讚賞。

回答

0

答案很簡單。不要啓動那麼多線程。考慮啓動儘可能多的線程,因爲您擁有邏輯CPU內核。起始線程是非常昂貴

當然,從來沒有啓動一個線程只是爲了做一件小事。保持線程並使用任務隊列爲他們提供很多(小)任務。

在這裏看到一個很好的例子,其中的線程數是同樣的問題:boost thread throwing exception "thread_resource_error: resource temporarily unavailable"

在這種情況下,我還以爲你可以通過增加每個任務的大小,獲得了很多的性能(不創建一個像素,但每掃描線例如)

+0

謝謝,這有助於加速了很多。我在第一個/主循環(行)下面像你說的那樣創建了一個線程,並將另外兩個線程移動到由線程調用的函數中。還有什麼可以做得更快的,比如清理,或者只是像8或10個線程一樣處於活動狀態,並且只是在'slot'打開之前正常調用這個函數呢? – Liger

+0

確保只有_n_個線程處於活動狀態的方法是沒有更多的線程。所以更重要的是巧妙地在可用線程中分塊處理。你可能應該專注於沒有太小的任務(開銷過大),而不是太大(併發性太少) – sehe

0

我相信這裏的區別在於當你決定加入線程。

在第一段代碼中,您可以在假定的源圖像的每個像素處加入線程。在第二段代碼中,你只在最後一次加入線程。

線程同步是昂貴的,往往是並行程序的瓶頸,因爲你基本上暫停任何新的線程執行,直到ALL線程需要同步的,在這種情況下是所有活躍的線程,完成運行。

如果最內層循環(帶im的那個)的迭代不相互依賴,我建議您在整個最外層循環完成後加入這些線程。

+0

謝謝,這有助於加快了一點 – Liger