在 OpenMP 和 Pthreads 中使用锁
我有一个同时使用 Pthreads 和 OpenMP 的程序。基本上,使用 Pthreads 创建 2 个线程(线程 A 和 B)来执行工作,在线程 A 中,OpenMP 用于并行化 for 循环。
如果我有一个由 OpenMP 线程和线程 B 访问的全局变量,我可以使用 OpenMP 中的锁来确保没有竞争条件吗?
我的想法是:
int count = 0;
pthread_create(&ThreadA, &attr, WorkA, NULL);
pthread_create(&ThreadB, &attr, WorkB, NULL);
void *WorkA (void *t)
{
#pragma omp parallel for
for (i = 0 ; i < N ; i++)
{
// Do some work
#pragma omp critical
{
// Do some other work
OMP_SET_LOCK(&lock);
count++;
OMP_UNSET_LOCK(&lock);
}
}
}
void *WorkB (void *t)
{
if (count > 0)
{
OMP_SET_LOCK(&lock);
count--;
OMP_UNSET_LOCK(&lock);
// Do some work
}
}
谢谢。
I have a program that uses both Pthreads and OpenMP. Basically, 2 threads (Thread A and B) are created using Pthreads to do work, and in Thread A, OpenMP is used to parallelize a for loop.
If I have a global variable that is accessed by the OpenMP threads and also Thread B, can I use the lock in OpenMP to ensure I have no race conditions?
What I have in mind:
int count = 0;
pthread_create(&ThreadA, &attr, WorkA, NULL);
pthread_create(&ThreadB, &attr, WorkB, NULL);
void *WorkA (void *t)
{
#pragma omp parallel for
for (i = 0 ; i < N ; i++)
{
// Do some work
#pragma omp critical
{
// Do some other work
OMP_SET_LOCK(&lock);
count++;
OMP_UNSET_LOCK(&lock);
}
}
}
void *WorkB (void *t)
{
if (count > 0)
{
OMP_SET_LOCK(&lock);
count--;
OMP_UNSET_LOCK(&lock);
// Do some work
}
}
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 OpenMP 实现,底层代码很可能会使用 pthread。也就是说,OpenMP 规范没有提及不同的线程模型是否可以“很好地协同工作”。这可能有效也可能无效,具体取决于您所使用的实现是否已完成允许其执行的工作。不幸的是,我只能说,检查您正在使用的产品的文档,看看它是否有说明。我相信大多数实现都试图让它发挥作用。
Depending on the OpenMP implementation, the underlying code may well use pthreads. That said, the OpenMP specification says nothing about whether or not different threading models will "play nicely together". This may or may not work depending on whether the implementation you are using has done the work to allow it to. Unfortunately, all I can say, is to check the documentation for the product you are using and see if it says anything. I believe most implementations have tried to allow this to work.
使用原子操作来更改计数。首先,使用互斥锁来保护简单的 ++ 或 -- 是不必要的。互斥锁用于保护任何其他方式无法原子完成的事情。其次,在我看来,性能 = 1/((locks)^5)。即锁迅速成为线程应用程序中性能问题的根源,因此请避免使用它们。第三……原子操作可以很好地与 OpenMP 配合使用。使用 __sync_add_and_fetch 或类似的原子操作来更改数数。它是在芯片上的硬件中实现的,因此它仅比 ++ 或 -- 慢约 2 倍,而使用互斥锁时则慢约 40 倍。
Use atomic operations to change count. First, using a mutex to protect a simple ++ or -- is unnecessary. Mutexes are for protecting anything that cannot be done atomically any other way. Second, in my mind, performance = 1/((locks)^5). I.e. locks rapidly become the source of performance problems in threaded apps, so avoid them. Third...the atomic op will play nicely with OpenMP. Use __sync_add_and_fetch or a similar atomic operation to change count. Its implemented in hardware on the chip, so its only about ~2x slower than ++ or --, compared to about 40x slower when using mutexes.