gpt4 book ai didi

c++ - 简单的基于任务的 OpenMP 应用程序挂起

转载 作者:搜寻专家 更新时间:2023-10-31 01:34:52 24 4
gpt4 key购买 nike

下面的小程序 ( online version ) 试图计算一个 64 x 64 正方形的面积,方法是递归地分成四个正方形,直到最小的正方形具有单位长度(几乎不是最优的)。但由于某种原因,程序挂起。哪里做错了?

#include <iostream>

unsigned compute( unsigned length )
{
if( length == 1 ) return length * length;

unsigned a[4] , area = 0 , len = length/2;

for( unsigned i = 0; i < 4; ++i )
{
#pragma omp task
{
a[i] = compute( len );
}

#pragma omp single
{
area += a[i];
}
}

return area;
}

int main()
{
unsigned area , length = 64;

#pragma omp parallel
{
area = compute( length );
}

std::cout << area << std::endl;
}

最佳答案

single 构造充当团队中所有线程的隐式屏障。然而,并非团队中的所有线程都会遇到这个单 block ,因为不同的线程在不同的递归深度下工作。这就是您的应用程序挂起的原因。

无论如何,您的代码都不正确。在您的任务 block 之后,a[i] 尚未分配,因此您不能立即使用它!您必须等待任务完成。当然你不应该在循环内这样做,否则任务分配不会利用任何并行性。解决方案是在循环结束时执行此操作。您还必须将 a 指定为共享,以使输出可见:

for( unsigned i = 0; i < 4; ++i )
{
#pragma omp task shared(a)
{
a[i] = compute( len );
}
}
#pragma omp taskwait
for( unsigned i = 0; i < 4; ++i )
{
area += a[i];
}

请注意,缩减并没有包含一个单个结构!计算由任务执行,因此只有一个线程应该拥有自己的本地区域。但是,在您第一次生成任何任务之前,您需要一个 single 构造:

#pragma omp parallel
#pragma omp single
{
area = compute( length );
}

简单来说,这会打开一个包含一组线程的并行区域,并且只有一个线程开始初始计算。其他线程将使用 task 构造来获取稍后由该初始线程生成的任务。这就是任务分配的意义所在。

关于c++ - 简单的基于任务的 OpenMP 应用程序挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38460374/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com