OpenMP平行还原(最小)结果不正确
我正在使用OpenMP减少(Min)来在所有参与线程上并行部分中获取最少的锁定获取数量。 在平行部分中打印每个线程计数器时,我会得到正确的结果,但是在平行部分之后,最小计数器在0。 这是代码:
int counter = 0, maxV, minV;
bool _continue = true; //variable to indicate when one second is over
#pragma omp parallel private(id) shared(lock, _continue) reduction(min:minV) reduction(+:counter) reduction(max:maxV)
{
id = omp_get_thread_num();
if(id == 0)
{
auto start = std::chrono::high_resolution_clock::now(); //start time measurement
while(_continue)
{
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> elapsed = finish - start;
if(elapsed.count() > std::chrono::microseconds(sec).count())
{
_continue = false;
}
}
}
else
{
while(_continue) //during timeframe, try to obtain lock as often as possible
{
lock.lock(id);
lock.unlock(id);
counter++;
}
minV = counter;
maxV = counter;
}
#pragma omp critical
{
std::cout << id << ": " << minV << std::endl;
}
}
std::cout << minV << std::endl;
典型输出类似:
0: 2147483647
7: 256985
4: 255973
1: 256975
6: 255740
5: 256658
3: 256856
2: 256943
0
因此,即使对于线程0,也没有获取锁的线程,而是花时间,MINV在还原列表类型(int)中正确初始化为最大代表数字(INT) 。
根据我选择的编译器选项,我可以将MINV的结果(COUT中的最后一行)更改为以下值(总是错误的...):
MINV = 32767 | -std = C ++ 14 -Fopenmp
minv = 0 | -std = C ++ 14 -Fopenmp -O3
minv = 32766 | -std = C ++ 14 -Fopenmp -Wall
Minv = 32767 | -STD = C ++ 14 -Fopenmp -wall -Pedantic -March =本机-FConcepts,
所以我认为它与我的编译器选项有关吗?奇怪的是,最高和降低似乎有效...
任何帮助都将受到赞赏。
i am using OpenMP reduction(min) to get the minimum number of lock acquisitions in a parallel section over all participating threads.
When printing each threads counter inside the parallel section, I get correct results but after the parallel section, the min counter is at 0.
This is the code:
int counter = 0, maxV, minV;
bool _continue = true; //variable to indicate when one second is over
#pragma omp parallel private(id) shared(lock, _continue) reduction(min:minV) reduction(+:counter) reduction(max:maxV)
{
id = omp_get_thread_num();
if(id == 0)
{
auto start = std::chrono::high_resolution_clock::now(); //start time measurement
while(_continue)
{
auto finish = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> elapsed = finish - start;
if(elapsed.count() > std::chrono::microseconds(sec).count())
{
_continue = false;
}
}
}
else
{
while(_continue) //during timeframe, try to obtain lock as often as possible
{
lock.lock(id);
lock.unlock(id);
counter++;
}
minV = counter;
maxV = counter;
}
#pragma omp critical
{
std::cout << id << ": " << minV << std::endl;
}
}
std::cout << minV << std::endl;
The typical output is something like:
0: 2147483647
7: 256985
4: 255973
1: 256975
6: 255740
5: 256658
3: 256856
2: 256943
0
So even for thread 0, the thread that is not acquiring the lock but just taking the time, the minV is correctly initialized as largest representable number in the reduction list item type (int).
Depending on what compiler options I choose, I can alter the result of minV (last line in cout) to the following values (always wrong...):
minV = 32767 | -std=c++14 -fopenmp
minV = 0 | -std=c++14 -fopenmp -O3
minV = 32766 | -std=c++14 -fopenmp -Wall
minV = 32767 | -std=c++14 -fopenmp -Wall -pedantic -march=native -fconcepts
So I assume it has something to do with my compiler options? Strangely though, the max and sum reduction appear to work fine...
Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您在OMP内部使用的INIT值与用户代码中的初始值之间存在混淆。部分减少是用内部值完成的,但是在某个时候,还必须对用户供使用的初始值进行减少。如果您不设置它,可能会发生任何事情。
这是一张可爱的图片: https://theartofhpc.com/pcce.com/pcse/pcse/omp-reduction。 html#initialValueForreductions
You have a confusion between the init value that OMP uses internally, and the init value from the user code. The partial reductions are done with the internal value, but at some point there also has to be a reduction against the user-supplied initial value. If you don't set that, anything can happen.
Here is a cute picture: https://theartofhpc.com/pcse/omp-reduction.html#Initialvalueforreductions