我正在用openMP计算一个项目。在这个项目中,我需要做一个计算,特别是:
gap = (DEFAULT_HEIGHT / nthreads);
其中DEFAULT_HEIGHT
是常量,nthreads
是并行区域内的线程数。我的问题是我无法计算并行区域外的变量gap
,因为我需要在里面知道nthreads
。但另一方面,我不想为每个线程计算gap
。此外,我无法设置这样的代码:
if(tid==0){
gap = (DEFAULT_HEIGHT / nthreads);
}
因为我不知道每个线程的执行顺序,所以可能是线程0从最后开始,而我需要gap
的所有其他计算都是错误的(因为它不会被设置) )。那么,有一种方法可以在没有这个问题的情况下进行一次这个计算吗?
由于
答案 0 :(得分:6)
确保gap
是共享变量并将其括在OpenMP single
指令中,例如
#pragma omp single
{
gap = (DEFAULT_HEIGHT / nthreads);
}
只有一个线程将执行single
指令中包含的代码,其他线程将在所附代码块的末尾等待。
另一种方法是将gap
设为私有,让所有线程计算自己的值。这可能更快,single
选项需要一些总是需要时间的同步。如果您担心,请尝试两者并比较结果。 (我认为这就是ComicSansMS的建议。)
答案 1 :(得分:3)
这是权衡:如果只有一个线程进行计算,则必须同步对该值的访问。特别是,只想读取值的线程必须同步,因为它们通常没有其他方法来确定写入是否已经完成。如果变量的初始化是如此昂贵,以至于它可以弥补这一点,那么你应该去做。但它可能不是。
请记住,您可以在从内存中获取数据所花费的时间内对CPU进行大量计算。正确同步此访问将消耗额外的周期,并可能导致不希望的停滞效应。更糟糕的是,这种影响的影响通常会随着共享资源的线程数量的增加而大幅增加。
在并行计算中接受一些冗余并不罕见,因为同步开销很容易消除冗余数据的已保存计算时间带来的任何好处。