我有一个程序可以调用大约100个函数 - 我想为每个函数使用omp_set_num_threads。我应该在每次调用ith功能之前使用它吗?或者我可以使用它一次,让我们说在int main(int argc, char **argv)
之后,它将用于每个函数调用吗?
看起来像这样:
omp_set_num_threads(val);
if(call_me_i)
call_ith_function;
omp_set_num_threads(val);
if(call_me_i+1)
call_ith+1_function;
...
答案 0 :(得分:2)
简短回答:您只需要设置一次线程数,除非您想稍后更改它。一旦设定,就会“记住”。
听起来我觉得你有各自的函数,其中包含一些并行代码,并且你想确保它们确实并行运行。如果您有大量if
语句,通常需要考虑switch
。
omp_set_num_threads(val); //<<< set just once
switch(whatFunction) {
case fun1:
callFunction1();
break;
case fun2:
callFunction2();
break;
default:
// etc
}
void callFunction1() {
int ii;
#pragma omp parallel
// <<<< just this for loop will run in parallel >>>>>
for(ii=0; ii<100; ii++) {
// do stuff
}
printf("done\n"); printf("really done\n"); printf("totally done\n"); // << NOT in parallel
}
void callFunction2() {
int jj;
for(jj=0; jj<100; jj++) {
// do stuff
} // <<<< this loop does NOT run in parallel since there is no #pragma in front of it
}
答案 1 :(得分:2)
你永远不应该使用它!
一旦你使用它,你就会阻止你的代码在别人的机器上运行,或者在你明年或之后购买的机器上运行(此时你会忘记你强迫它)。
如果您使用英特尔编译器,它将默认使用进程可用的所有硬件线程(即,不会从进程的亲和力掩码中屏蔽掉),而无需您执行任何操作。 Gcc可能表现不同,但肯定会尊重OMP_NUM_THREADS环境变量,这是选择要使用的线程数的更好位置。
将当前机器的知识构建到代码中只是一个坏主意,因为(正如我们现在所知),代码的寿命比硬件长得多。
答案 2 :(得分:0)
你应该更清楚,但我会试着解释一下它是如何运作的。
我的cpu看起来像这样:
Architecture: i686
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 28
Stepping: 10
CPU MHz: 1000.000
BogoMIPS: 3325.16
Virtualization: VT-x
L1d cache: 24K
L1i cache: 32K
L2 cache: 512K
好吧,我有4个逻辑cpu。这意味着 omp_get_max_threads()应返回4.
这是我的示例代码:
#include<omp.h>
#include<iostream>
using namespace std;
int main()
{
cout << omp_get_num_threads() << " " << omp_get_max_threads() << endl;
omp_set_num_threads(omp_get_max_threads());
cout << omp_get_num_threads() << " " << omp_get_max_threads() << endl;
#pragma omp parallel
{
#pragma omp single
cout << omp_get_num_threads() << " " << omp_get_max_threads() << endl;
cout << "x" << endl;
}
return 0;
}
及其输出:
1 4
1 4
4 4
x
x
x
x
正如您所看到的, omp_set_num_threads()在开始时被调用过一次。然而,此调用并不意味着你从那时开始并行运行。
要并行运行指令,您需要使用 #pragma omp parallel 。如果它位于 {...} 部分之前,则整个部分将并行运行。如果这是在正常行之前,它将仅影响此行。第二种方法出现在 #pragma omp single 之后。我称之为,因为我不希望每个线程都打印下一行。我只想要一个人来打印它。
无论如何,你需要的只是做以下事情:
omp_set_num_threads(omp_get_max_threads());
#pragma omp parallel
{
if(call_me_i)
call_ith_function;
if(call_me_i+1)
call_ith+1_function;
}