代码
double t;
double limit = 10;
double result = 1000;
int i;
#pragma omp parallel sections default(none) firstprivate(result) lastprivate(result) private(t) shared(limit)
{
#pragma omp section
{
printf("Section1: result = %f\n", result);
result += 55;
printf("Section1: result = %f\n", result);
}
#pragma omp section
{
printf("Section2: result = %f\n", result);
result += 3628800;
printf("Section2: result = %f\n", result);
}
}
printf("result1 = %0.0lf\n", result);
结果是
Section1: result = 1000.000000
Section1: result = 1055.000000
Section2: result = 1000.000000
Section2: result = 3629800.000000
result1 = 3629800
OR
Section1: result = 1000.000000
Section1: result = 1055.000000
Section2: result = 1055.000000
Section2: result = 3629855.000000
result1 = 3629855
在VS2010中,我使用firstprivate初始化部分中的result
我认为,在第1节或第2节中,结果应该在操作+
但是,当我运行程序时,结果可能会在第2部分初始化为1055。 有人可以告诉我为什么吗?
答案 0 :(得分:1)
OpenMP标准中没有任何内容可以保证不同的线程执行各个部分。 MSVC的OpenMP运行时动态分配部分,即一旦线程准备就绪,就会为其分配队列中的下一部分。在这种情况下,主线程完成执行第一部分时,可能仍在创建其他线程。会发生什么是主线程将开始执行第二部分。确切地说,该示例显示在MSDN中sections
的描述中的示例中。由于(first|last)private
子句适用于每个主题而不是每个部分,result
在第二部分中的初始值为1055.0
。
你可以很容易地看到它是如何发生的:
#pragma omp section
{
printf("Section1: thread = %d\n", omp_get_thread_num());
printf("Section1: result = %f\n", result);
result += 55;
printf("Section1: result = %f\n", result);
}
#pragma omp section
{
printf("Section2: thread = %d\n", omp_get_thread_num());
printf("Section2: result = %f\n", result);
result += 3628800;
printf("Section2: result = %f\n", result);
}
现在,当实现问题的第二个样本输出时,检查两个部分的线程ID是否相同,以及当实现第一个输出时它们是否不同。
OpenMP部分应该是独立的。在您的情况下,result
变量携带的两个部分之间存在数据依赖性。