use*_*921 5 c c++ parallel-processing openmp
我正在使用 OpenMP 并且我想生成线程,以便一个线程执行一段代码并完成,与运行并行 for 循环迭代的 N 个线程并行。
执行应该是这样的:
Section A (one thread) || Section B (parallel-for, multiple threads)
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
V || V V V V V V V V V V
Run Code Online (Sandbox Code Playgroud)
我不能只用 a 编写并行 for,#pragma omp once因为我不希望执行 A 部分的线程执行 for 循环。
我试过这个:
#pragma omp parallel sections {
#pragma omp section
{
// Section A
}
#pragma omp section
{
// Section B;
#pragma omp parallel for
for (int i = 0; i < x; ++i)
something();
}
}
Run Code Online (Sandbox Code Playgroud)
然而,parallel-for 总是只用一个线程执行(我知道因为我打印了循环体,omp_get_thread_num()它们都是相同的数字,1 或 0 取决于两个线程中的哪个线程执行了第二个并行部分)。
我也试过
#pragma omp sections {
#pragma omp section
{
// Section A
}
#pragma omp section
{
// Section B;
#pragma omp parallel for
for (int i = 0; i < x; ++i)
something();
}
}
Run Code Online (Sandbox Code Playgroud)
这允许 for 循环使用多个线程执行,但它使部分非并行,并且第一部分在第二部分之前顺序执行。
我需要的是两种方法的组合,其中 for 循环的每次迭代和第一部分都并行运行。
嵌套并行性必须显式设置,因为在大多数实现中默认情况下禁用它。根据 OpenMP 4.0 标准,您必须设置OMP_NESTED环境变量:
OMP_NESTED 环境变量通过设置 Nest-var ICV 的初始值来控制嵌套并行性。该环境变量的值必须为 true 或 false。如果环境变量设置为true,则启用嵌套并行性;如果设置为 false,则禁用嵌套并行性。如果 OMP_NESTED 的值既不是 true 也不是 false,则程序的行为是实现定义的。
以下行应该适用于 bash:
export OMP_NESTED=true
Run Code Online (Sandbox Code Playgroud)
此外,正如 @HristoIliev 在下面的评论中指出的那样,您很可能希望设置OMP_NUM_THREADS环境变量来调整性能。引用标准:
此环境变量的值必须是正整数值的列表。列表的值设置用于相应嵌套级别的并行区域的线程数。
这意味着应该将 的值设置OMP_NUM_THREADS为类似于n,n-1CPUn核心数。例如:
export OMP_NUM_THREADS=8,7
Run Code Online (Sandbox Code Playgroud)
对于 8 核系统(从下面的评论复制的示例)。