Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;带有private和shared子句的OpenMP计算错误_C++_Multithreading_Openmp - Fatal编程技术网

C++ C++;带有private和shared子句的OpenMP计算错误

C++ C++;带有private和shared子句的OpenMP计算错误,c++,multithreading,openmp,C++,Multithreading,Openmp,我有一个循环要与OpenMP并行,但有多个计算错误,可能是因为我不了解OpenMP的多线程概念: for ( int i = -X/2; i < X/2; ++i ) { base.y = anchor + i*rho_step; temp = some_function( base ); if( temp > response ) { buffer.y = base.y; response = temp; }

我有一个循环要与OpenMP并行,但有多个计算错误,可能是因为我不了解OpenMP的多线程概念:

for ( int i = -X/2; i < X/2; ++i )
{
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
}

有什么问题吗?(
anchor
rho_step
是这个循环中的常量)

为了让代码处理
缓冲区的跨线程变量和
响应变量,您需要为它们使用一些每个线程的局部变量,并对它们执行最终的缩减以更新它们的共享对应项

以下是它的外观(未经测试):

#pragma omp parallel firstprivate(基本)
{
自动本地响应=响应;
自动本地缓冲区=缓冲区;
#pragma omp for
对于(int i=-X/2;i本地响应)
{
localBuffer.y=base.y;
localResponse=temp;
}
}
#pragma-omp-critical
{
if(localResponse>response)
{
buffer.y=localBuffer.y;
响应=本地响应;
}
}
}

不幸的是,这产生了同样的结果。如果
buffer
response
是共享的,并且处于关键部分,我不明白为什么我们需要每个线程的局部变量。对于每个不同的
i
我们有不同的
base.y
temp
,我们只需管理每个线程有自己的
base.y
-s和
temp
-s,并检查它们是否必须逐个修改
缓冲区和
响应。(很抱歉我的知识不完善。)我只是做了一个更改,将
base
firstprivate
放在这里,因为不清楚其他字段在上下文中是否重要。无论如何,我的方法的要点是,最终的归约(
临界
部分)在并行循环之外,但在并行部分之内。它只在最后出现一次,而不是像在您的代码中那样在每次迭代中出现。
firstprivate
解决了问题,现在您和我的版本都可以工作了,谢谢!尽管您的版本存在变量
缓冲区
响应
的争用条件,但要小心(这是制作本地版本和在
关键
部分进行最终缩减的全部要点)。因此,尽管您的版本似乎与
firstprivate
一起工作,但它本质上是错误的。在我看来,它似乎存在数据依赖关系:
response
可能会更改,并直接影响以后的循环过程。如果是这样,您就无法使用任何多线程工具轻松地加速循环。只有当
某些函数
需要大量时间时,才可以添加多线程。
响应
仅在if条件为true时才会更改。some_函数做了很多事情,这就是为什么我试图节省运行时间。谢谢你的评论!
#pragma omp parallel for shared (buffer, response) private(base, temp)
for ( int i = -X/2; i < X/2; ++i )
{
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
}
omp_lock_t writelock;
omp_init_lock(&writelock);
omp_set_num_threads (4);

#pragma omp parallel for
for ( int i = -X/2; i < X/2; ++i )
{
    omp_set_lock(&writelock);
    base.y = anchor + i*rho_step;
    temp = some_function( base );
    if( temp > response )
    {
        buffer.y = base.y;
        response = temp;
    }
    omp_unset_lock(&writelock);
}
omp_destroy_lock(&writelock);
#pragma omp parallel firstprivate( base )
{
    auto localResponse = response;
    auto localBuffer = buffer;
    #pragma omp for
    for ( int i = -X/2; i < X/2; ++i )
    {
        base.y = anchor + i * rho_step;
        auto temp = some_function( base );
        if ( temp > localResponse )
        {
            localBuffer.y = base.y;
            localResponse = temp;
        }
    }
    #pragma omp critical
    {
        if ( localResponse > response )
        {
            buffer.y = localBuffer.y;
            response = localResponse;
        }
    }
}