我有一个同时使用Pthread和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
}
}
谢谢。
答案 0 :(得分:1)
根据OpenMP实现,底层代码可能会使用pthread。也就是说,OpenMP规范没有说明不同的线程模型是否会“很好地协同工作”。这可能会也可能不会起作用,具体取决于您使用的实现是否已完成允许它的工作。不幸的是,我只能检查您正在使用的产品的文档,看看它是否有任何说明。我相信大多数实现都试图让它工作。
答案 1 :(得分:1)
使用原子操作来改变计数。首先,使用互斥锁来保护简单的++或 - 是不必要的。互斥体用于保护任何其他方式无法原子化的东西。其次,在我看来,性能= 1 /((锁定)^ 5)。即锁定迅速成为线程应用程序中性能问题的根源,因此请避免使用它们。第三......原子操作将与OpenMP很好地配合。使用__sync_add_and_fetch或类似的原子操作来改变计数。它在芯片上的硬件中实现,因此它仅比++或 - 慢约2倍,而使用互斥量则慢约40倍。