【问题标题】:Is there any way to force openmp to get desired number of threads?有什么方法可以强制 openmp 获得所需的线程数?
【发布时间】:2021-06-19 19:15:16
【问题描述】:
我正在尝试通过使用子句或在环境中设置来设置我的线程数的各种方法,但它们都没有奏效。有什么方法可以强制 OpenMP 获取自定义数量的线程?
#include <cmath>
#include <random>
#include <iostream>
#include <chrono>
#include <cfloat>
#include <iomanip>
#include <cstdlib>
#include <omp.h>
#include <trng/yarn2.hpp>
#include <trng/mt19937_64.hpp>
#include <trng/uniform01_dist.hpp>
using namespace std;
double function(double x) {
return cos(x) / landa;
}
int main() {
int rank;
const int N = 1000000;
double sum = 0.0;
omp_set_num_threads(6);
omp_set_dynamic(0);
#pragma omp reduction(+ : sum) //default(none)
{
trng::yarn2 r;
int size = omp_get_num_threads();
cout<<size<<endl;
int rank = omp_get_thread_num();
trng::uniform01_dist<> u;
r.jump(2 * (rank * N / size));
for (long i = rank * N/ size; i < (rank + 1) * N / size; ++i) {
double x= u(r);
x = (-1.0) * log(1.0 - x);
sum = sum+function(x);
}
}
return 0;
}
【问题讨论】:
标签:
c++
multithreading
parallel-processing
openmp
【解决方案1】:
#pragma omp num_threads(6) reduction(+ : sum) //default(none)
{
//OMP_NUM_THREADS=6;
omp_set_num_threads(6);
这是错误的,你需要在parallel region之前设置线程数。此外,您在那里缺少 parallel 子句。所以你可以这样做:
omp_set_num_threads(6)
#pragma omp parallel reduction(+ : sum)
{
...
}
或
#pragma omp parallel num_threads(6) reduction(+ : sum)
你不需要两者。
第一种方法(ie,omp_set_num_threads)设置所有后续并行区域要使用的线程数,而第二种方法num_threads 显式设置要使用的线程数只能通过封闭的parallel region。
如果还是不行,那么你必须explicitly disable dynamic teams:
通过添加以下调用:
omp_set_dynamic(0);
#pragma omp parallel ...
{
...
}
来自source 可以阅读:
总结 omp_set_dynamic 例程启用或禁用 dynamic
调整可用于执行的线程数
通过设置 dyn-var ICV 的值来实现后续并行区域。
【解决方案2】:
执行此操作的正确方法是在您的程序中使用以下方法之一:
#include <stdio.h>
#include <omp.h>
int main(void) {
// option 1:
omp_set_num_threads(3);
#pragma omp parallel
{
#pragma omp single
{
printf("Number of threads: %d\n", omp_get_num_threads());
}
}
// option 2:
#pragma omp parallel num_threads(12)
{
#pragma omp single
{
printf("Number of threads: %d\n", omp_get_num_threads());
}
}
return 0;
}
您可以使用 next 和所有未来并行区域所需的线程数调用 omp_set_num_threads 函数(代码中的选项 1)。注意,你必须从程序的主线程中调用它,如果你把这个调用放到一个并行区域中,你会得到不同的效果。
您还可以使用num_threads 子句来设置特定并行区域的线程数。其他并行区域不会受此影响。在您发布的代码中,语法错误(您的 OpenMP 指令中缺少 parallel)。不确定,为什么编译器没有告诉你。
最后,您可以通过在 shell 中设置 OMP_NUM_THREADS 来设置程序所有并行区域的线程数,例如 bash: export OMP_NUM_THREADS=27。
PS:请尝试提供更小的示例,这些示例可以实际编译并仍然显示您遇到的问题。这让人们更容易看到您的问题并为您提供解决方案。