我有以下顺序代码:
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
// Inner body
}
}
我的目标是简单地并行化内部循环。可以这样完成:
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
#pragma omp parallel for
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
// Inner body
}
}
此代码的问题是,在外循环的每次运行中都会产生新线程。为了加快此代码的速度,我想提前创建一个线程组并多次使用它们。我发现为此目的有一条指令#pragma omp for
。
#pragma omp parallel
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
#pragma omp for
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
// Inner body
}
}
但是,如果我正确理解指令#pragma omp parallel
的用法,则会导致外循环运行多次。这是正确的吗?
修改: 这里是一个更详细的示例:
// Let say that the image is represented as an array of pixels
// where pixels is just one integer.
std::vector<Image> images = getImages();
for (auto & image : images) { // Loop over all images
#pragma omp parallel for
for (unsigned j = 0; j < image.size(); ++j) { // Loop over each pixel
image.at(j) += addMagicConstant(j);
}
}
目标:我想生成一组线程,然后重复使用它们仅并行化内部循环(=遍历图像像素)。
答案 0 :(得分:0)
您的代码完全有效,并且确实可以正常工作:
#pragma omp parallel
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
// Outer body
#pragma omp for
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
// Inner body
}
}
#pragma omp parallel
将产生线程。然后,每个线程将继续通过外部循环。在每次循环迭代时,线程将到达#pragma omp for
,并且内部循环将在线程之间分布。每个omp for
块的末尾都有一个隐式屏障,因此线程将等到内部循环完成后再进行下一个外部循环迭代。
如果可以确保所有线程都进入循环,则可以在另一个for或while循环中或在条件部分中具有omp for
分布式循环。
但是禁止使用诸如:
#pragma omp parallel
for (unsigned ii= 0; ii< omp_thread_num(); ++ii) { // Number of iteration of outer loop depends on the thread
// Outer body
#pragma omp for
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
// Inner body
}
}
或
#pragma omp parallel
if(condition_depending_on_thread_num) {
#pragma omp for
for (unsigned j = 0; j < maxSize; ++j) { // Loop
// Inner body
}
}
答案 1 :(得分:-1)
您尝试过吗:
#pragma omp parallel for
for (unsigned item = 0; item < totalItems; ++item) { // Outer loop
for (unsigned j = 0; j < maxSize; ++j) { // Inner loop
}
}