赫鲁乌,
我有一个相当大的程序,我正在尝试线程化。到目前为止,这已经成功,并且基础都按预期工作。
我现在想在嵌套模式下用级联线程做一些花哨的工作。本质上,我希望主并行区域使用较低并行区域中的任何空闲线程。
详细介绍当前系统,主并行区域启动 10 个线程。我有 12 个内核,所以我可以再使用 2 个线程。第二个并行区域发生了一些繁重的计算,我希望前两个线程达到这一点,以便在那里建立一个新团队,每个有 2 个线程。在此之后对较低并行区域的每个新条目都将继续串行。
所以,这应该如下所示。
主要区域:10 个线程启动。
下部区域:2 个新线程已启动。
线程 1:下部区域有 2 个线程。
线程 2:下部区域有 2 个线程。
线程 3-10:下部区域有 1 个线程。
请记住,这些数字是为了清楚地提供对我的情况的具体描述,而不是程序运行的绝对和唯一情况。
编码:
main() {
...
...
omp_set_num_threads(n);
omp_set_dynamic(x);
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < iterations; i++) {
...
Compute();
...
}
}
}
在计算中
bool Compute() {
...
float nThreads = omp_get_thread_limit() - omp_get_num_threads();
nThreads = ceil(nThreads / omp_get_num_threads());
omp_set_num_threads((int)nThreads);
#pragma omp parallel
{
...
#pragma omp for
for (int i = 0; i < nReductSize; i++) {
...
}
}
}
现在,我的问题是为整个程序设置最高限制(即 OMP_THREAD_LIMIT)只能在程序外部工作。使用
export OMP_THREAD_LIMIT=5
从 bash 命令行效果很好。但我想在内部做。到目前为止,我已经尝试过
putenv("OMP_THREAD_LIMIT=12");
setenv("OMP_THREAD_LIMIT", "12", 1);
但是当我调用 omp_get_thread_limit() 或 getenv("OMP_THREAD_LIMIT") 时,我会得到古怪的返回值。即使我使用导出设置变量,调用 getenv("OMP_THREAD_LIMIT"); 返回 0。
所以,我想请你帮忙:如何在运行时正确设置 OMP_THREAD_LIMIT?
这是我设置线程默认值的主要功能。它在任何线程发生之前很好地执行:
#ifdef _OPENMP
const char *name = "OMP_THREAD_LIMIT";
const char *value = "5";
int overwrite = 1;
int success = setenv(name, value, overwrite);
cout << "Var set (0 is success): " << success << endl;
#endif
哦,setenv 报告设置变量成功。
编译器说
gcc44 (GCC) 4.4.7 20120313 (Red Hat 4.4.7-1)
标志
CCFLAGS = -c -O0 -fopenmp -g -msse -msse2 -msse3 -mfpmath=sse -std=c++0x
OpenMP 版本是 3.0。