我有這段代碼可以轉置具有回圈平鋪功能的矩陣。
void transposer(int n, int m, double *dst, const double *src) {
int blocksize;
for (int i = 0; i < n; i = blocksize) {
for (int j = 0; j < m; j = blocksize) {
// transpose the block beginning at [i,j]
for (int k = i; k < i blocksize; k) {
for (int l = j; l < j blocksize; l) {
dst[k l*n] = src[l k*m];
}
}
}
}
}
我想通過使用 OpenMP 的多執行緒來優化它,但是我不確定當有這么多嵌套的 for 回圈時該怎么辦。我想過只是添加#pragma omp parallel for,但這不只是并行化外回圈嗎?
uj5u.com熱心網友回復:
您可以使用折疊說明符在兩個回圈上并行化。
# pragma omp parallel for collapse(2)
for (int i = 0; i < n; i = blocksize) {
for (int j = 0; j < m; j = blocksize) {
// transpose the block beginning at [i,j]
for (int k = i; k < i blocksize; k) {
for (int l = j; l < j blocksize; l) {
dst[k l*n] = src[l k*m];
}
}
}
}
作為旁注,我認為您應該交換兩個最里面的回圈。通常,當您在順序寫入和順序讀取之間進行選擇時,寫入對性能更重要。
uj5u.com熱心網友回復:
我想過只是添加#pragma omp parallel for,但這不只是并行化外回圈嗎?
是的,要并行化多個連續回圈,您需要使用 OpenMP折疊子句。但是,請記住,在某些情況下,并行嵌套回圈可能會導致比僅并行單個回圈更慢的時間。崩潰使用更復雜的啟發式(比簡單的回圈并行化)在執行緒之間劃分回圈迭代,這可能導致開銷高于它提供的增益。
void transposer(int n, int m, double *dst, const double *src) {
int blocksize;
pragma omp parallel for collapse(2)
for (int i = 0; i < n; i = blocksize)
for (int j = 0; j < m; j = blocksize)
for (int k = i; k < i blocksize; k
for (int l = j; l < j blocksize; l)
dst[k l*n] = src[l k*m];
}
您應該嘗試使用單個回圈并行執行,然后并行執行兩個回圈并檢查結果。根據執行緒的數量、內核、矩陣的大小以及其他因素,順序運行實際上可能比并行版本更快。這在您的代碼中尤其如此,它不是 CPU 密集型(即 dst[k l*n] = src[l k*m];)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/418540.html
標籤:
