gpt4 book ai didi

c++ - fork 一次然后在不同的过程中使用线程?

转载 作者:行者123 更新时间:2023-11-30 04:09:24 25 4
gpt4 key购买 nike

如果我在主程序中 fork ,然后在单个指令中调用子例程,如果我在此子例程中输入 OMP 并行指令,行为会怎样?

我的猜测/希望是使用现有的线程,因为它们目前都应该没有任何关系。

伪示例:

double A[];

int main() {
#pragma omp parallel num_threads(2)
{
#pragma omp single
{
for (int t=0; t<1000; t++) {
evolve();
}
}
}
}

void evolve() {
#pragma omp parallel for num_threads(2)
for (int i=0; i<100; i++) {
do_stuff(i);
}
}

void do_stuff(int i) {
// expensive calculation on array element A[i]
}

由于 evolve() 经常被调用,在这里 fork 会导致很多开销,所以我想只做一次,然后调用 evolve()来自单个线程,并将对 do_stuff() 的调用工作拆分到现有线程上。

对于 Fortran,这似乎可行。在一个使用 2 个线程的简单示例中,我的速度提高了大约 80-90%。但是对于 C++,我得到了不同的行为,只有执行单个指令的线程用于 evolve()

中的循环

我在主程序中使用任务指令并将限制传递给 evolve() 解决了这个问题,但这看起来像是一个笨拙的解决方案...

为什么 Fortran 和 C++ 中的行为不同,C++ 中的解决方案是什么?

最佳答案

我相信孤立指令是您的情况下最干净的解决方案:

double A[];

int main() {
#pragma omp parallel num_threads(2)
{
// Each thread calls evolve() a thousand times
for (int t=0; t<1000; t++) {
evolve();
}
}
}

void evolve() {
// The orphaned construct inside evolve()
// will bind to the innermost parallel region
#pragma omp for
for (int i=0; i<100; i++) {
do_stuff(i);
} // Implicit thread synchronization
}

void do_stuff(int i) {
// expensive calculation on array element A[i]
}

这会起作用,因为(标准的第 2.6.1 节):

A loop region binds to the innermost enclosing parallel region

也就是说,在您的代码中您使用的是嵌套并行结构。为确保启用它们,您必须将环境变量 OMP_NESTED 设置为 true,否则(引用最新标准的附录 E):

OMP_NESTED environment variable: if the value is neither true nor false the behavior is implementation defined

关于c++ - fork 一次然后在不同的过程中使用线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21237590/

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