2017-03-07 45 views
0

我正在開發一些計算機視覺庫的公司工作。它部分包含了許多具有更復雜算法的矩陣運算。爲了使一切都變得更快,我們開始使用OpenMP來並行化我們可能必須在矩陣運算中執行的大量雙循環,以及更復雜的算法,這些算法可能會調用這些循環,有時甚至可能會調用其中的幾個。如何處理編譯指令中的OpenMP pragmas

我知道它不會給在其他編譯指示中使用OpenMP編譯指示的最佳性能。但儘管我們的複雜算法比它慢,但它仍然可以使一些基本操作更快。

舉個例子,這可能是發生的事情:

// in resize.c 
image resize_bilinear(const image& img, int rows, int cols) { 
image out(rows, cols); 
#pragma omp parallel for 
for (int i = 0; i < rows; ++i) { 
    for (int j = 0; j < cols; ++j) { 
    // bilinear interpolation to get out(i,j) 
    } 
} 
return out; 
} 

而且我們可能有地方:

// in more_complex.c 
std::vector<image> resize_all(const std::vector<image> imgs, int rows, int cols) { 
std::vector<image> out(imgs.size()); 
#pragma omp parallel for 
for (int i = 0; i < imgs.size(); ++i) { 
    out[i] = resize_bilinear(imgs[i], rows, cols); 
} 
} 

是否有可能使上編譯禁用所有的下編譯指示他將遇到?或者,如果我們使用OpenMP來並行化我們的所有庫,我們註定了嗎?

還有OMP_MAX_ACTIVE_LEVELS環境變量。但是有沒有辦法在編譯本身中控制它?

+0

您可以簡單地設計應用程序以僅在外部循環中使用'#pragma',因此您應該將其從內部函數中刪除。 – Jepessen

回答

1

您可以嘗試使用允許啓用或禁用嵌套並行的omp_set_nested

+0

是的,我剛剛看到了!這就是我想要的。就我個人而言,你知道是否有特殊情況可以爲某些地區設置?就像在一些編譯指示中一樣,沒有嵌套的並行性,但在其他情況下,它很好? – baptiste

+0

我從來沒有嘗試過,但考慮到這是一個函數,你可以使用這個函數來啓用/禁用你想要的嵌套並行。您可以在嵌套循環之前將其設置爲1,並在另一個嵌套循環之前將其設置爲0。 – Jepessen

+0

我強烈建議,除非你真的*知道你在做什麼,否則你應避免嵌套並行。它很容易過度訂購機器(在N個邏輯CPU上有N ** 2個線程),因此性能非常差。也可以看一看omp_in_parallel()和並行編譯指令中的「if」子句,它可以讓你只在需要的地方引入並行,哦,別忘了「omp parallel for」只是「omp parallel」其次是「omp for」,所以你可以有更大的平行區域。 –