在运行时设置OMP_THREAD_LIMIT的问题(c ++ gcc 4.4.7)

时间:2013-09-06 09:33:52

标签: c++ parallel-processing openmp

Heluuu,

我有一个相当大的程序,我正在尝试解决。到目前为止,这已经取得了成功,并且所有基础工作都按预期进行。

我现在想在嵌套模式下使用级联线程做一些奇特的工作。基本上,我希望主并行区域在较低的并行区域中使用任何自由线程。

要详细说明当前系统,主要并行区域将启动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();
            ...
        }
    }
}    

在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”)时,我得到了古怪的返回值。即使我用export设置变量,也要调用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。

3 个答案:

答案 0 :(得分:2)

这是OpenMP的正确实现,它忽略了程序内部环境的变化。如OpenMP 3.1标准,第159页中所述:

  

程序启动后对环境变量的修改,即使是   由程序本身修改,被OpenMP实现忽略。

您正在完成本段所述的内容。

OpenMP只允许通过omp_set_*函数更改这些参数,但是thread-limit-var ICV没有这样的函数:

  

但是,在执行OpenMP期间,可以修改某些ICV的设置   通过使用适当的指令子句或OpenMP API例程来编程。

我认为,您可以使用num_threads的{​​{1}}条款来实现您的目标。

答案 1 :(得分:2)

在程序启动后,无法使用OMP_THREAD_LIMIT(或任何其他OMP_*环境变量)更改OpenMP的行为;这些是供用户使用的。您可以让用户通过设置OMP_THREAD_LIMIT的脚本调用您的程序,然后调用您的程序,但这可能不是您在这种情况下需要做的事情。

OMP_NUM_THREADSomp_set_num_threadsnum_threads子句通常用于设置区域中运行的线程数。

答案 2 :(得分:0)

它可能是offtopic,但你可能想尝试openmp collapse而不是手工制作。