Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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
Concurrency::parallel_for是否有类似于omp_set_lock的命令?_Concurrency_Set_Locking_Openmp_Parallel For - Fatal编程技术网

Concurrency::parallel_for是否有类似于omp_set_lock的命令?

Concurrency::parallel_for是否有类似于omp_set_lock的命令?,concurrency,set,locking,openmp,parallel-for,Concurrency,Set,Locking,Openmp,Parallel For,我有一个类(比如粒子),它有一个变量(比如param1): 和包含粒子类的一些实例的std::vector vector <particle> Particles; 现在,我将把我的代码从openMP转换为并发库,我想知道是否有任何等效的命令可以在Concurrency::parallel_for loop中使用,而不是omp_set_lock,它可以在更新时锁定对象 提前感谢。我认为并发库是指微软的并发运行时。您的用例实际上是一个关键部分,因此并发性提供了并发::关键部分,这是一

我有一个类(比如粒子),它有一个变量(比如param1):

和包含粒子类的一些实例的std::vector

vector <particle> Particles;
现在,我将把我的代码从openMP转换为并发库,我想知道是否有任何等效的命令可以在Concurrency::parallel_for loop中使用,而不是omp_set_lock,它可以在更新时锁定对象


提前感谢。

我认为并发库是指微软的并发运行时。您的用例实际上是一个关键部分,因此并发性提供了
并发::关键部分
,这是一个不可重入的互斥锁:

using namespace concurrency;

class particle
{
    double param1;
    . . .
    critical_section particle_lck;
    . . .
};
然后,临界截面变为:

currentParticle->particle_lck.lock();
currentParticle->param1 += anything;
currentParticle->particle_lck.unlock();
如果您更喜欢范围化方法,请使用
并发::关键部分::范围化锁定

{
   critical_section::scoped_lock guard(currentParticle->particle_lck);
   currentParticle->param1 += anything;
}
scoped_lock
是一个简单的包装器。它引用一个
critical\u节
对象,在构造函数中调用
lock()
,然后在析构函数中调用
unlock()
,因此当锁超出范围时,它会释放锁


正如Jim Cownie所解释的,将锁用于原子操作可以更有效地完成的事情是一种过分的做法。在OpenMP中,通常会执行以下操作:

#pragma omp atomic update
currentParticle->param1 += anything;

标准C++中的原子操作需要使用特殊的原子类型,而这些仅用于从C++ 20开始的浮点类型,因此您的代码将是(假设C++ 20编译器):


并发不提供自己的原子类型。相反,它依赖于<代码>可组合< /COD>类提供与OpenMP的子句>的等价性。< /P>假设+=不是一个复杂的重载C++操作符,并且“任何”都可以并行地安全执行,需要阅读OpenMP原子,因为使用它们可以完全避免锁。(我知道这似乎是偏离主题,但也许你应该考虑STD::原子用于PARAM1,这将需要一些技巧,因为在大多数C++标准中没有浮点/双原子,但是你可以用CMPXCHG实现你需要的)。亲爱的Hristo,非常感谢。我尝试了“pragma omp原子更新”,但没有获得更多的效率。当然,我使用的是VS2015和/Ox优化,而且我省略了“更新”关键字。它很常见吗?@KhodaeiAhmadAli OpenMP 3.1引入了四种
原子
子类型,可以更好地捕捉您的意图,并允许编译器使用适当的低级实现。使用
read
write
update
capture
子句指定,其中
capture
等同于没有子句的表单。Visual Studio仅支持OpenMP 2.0,因此您无法添加
update
{
   critical_section::scoped_lock guard(currentParticle->particle_lck);
   currentParticle->param1 += anything;
}
#pragma omp atomic update
currentParticle->param1 += anything;
#include <atomic>

class particle
{
    std::atomic<double> param1;
    . . .
};
currentParticle->param1.fetch_add(anything, std::memory_order_relaxed);