考虑下面的代码,即使没有循环,我们可以认为它是并行的吗?
#include <omp.h>
int main(void) {
#pragma omp parallel
{
int a = 1;
a = 0;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
直接答案:
是的,在这里,您的代码部分,
int a = 1;
a = 0;
Run Code Online (Sandbox Code Playgroud)
并行运行,P次,其中P是机器上的核心数.
例如在四核机器上,以下代码(带有相关的导入),
int main(void) {
#pragma omp parallel
{
printf("Thread number %d", omp_get_thread_num());
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
Thread number 0
Thread number 1
Thread number 2
Thread number 3
Run Code Online (Sandbox Code Playgroud)
请注意,当并行运行时,无法保证输出的顺序,因此输出可能就像:
Thread number 1
Thread number 2
Thread number 0
Thread number 3
Run Code Online (Sandbox Code Playgroud)
另外,如果你想指定并行区域中使用的线程数,而不是#pragma omp parallel你可以编写,#pragma omp parallel num_threads(4).
进一步说明:
如果您仍然感到困惑,那么更好地理解并行for循环和并行代码区域之间的区别可能会有所帮助.
#pragma omp parallel告诉编译器可以并行执行以下代码块.它保证在继续后续代码之前,并行区域内的所有代码都已完成执行.
在下面(玩具)示例中,程序员保证在并行区域之后,阵列将所有条目设置为零.
int *arr = malloc(sizeof(int) * 128);
const int P = omp_get_max_threads();
#pragma omp parallel num_threads(P)
{
int local_start = omp_get_thread_num();
int local_end = local_start + (100 / P);
for (int i = local_start; i < local_end; ++i) {
arr[i] = 0;
}
}
// any code from here onward is guaranteed that arr contains all zeros!
Run Code Online (Sandbox Code Playgroud)
忽略调度中的差异,此任务可以使用并行for循环等效地完成,如下所示:
int *arr = malloc(sizeof(int) * 128);
const int P = omp_get_max_threads();
#pragma omp parallel num_threads(P) for
for (int i = 0; i < 128; ++i) {
arr[i] = 0;
}
// any code from here onward is guaranteed that arr contains all zeros!
Run Code Online (Sandbox Code Playgroud)
本质上,#pragma omp parallel使您能够描述可以并行执行的代码区域 - 这比并行for循环更灵活.相反,#pragma omp parallel for通常应该用于通过独立迭代来并行化循环.
如果您愿意,我可以进一步详细说明性能上的差异.