OpenMP:锁定对单个数组元素的访问?

时间:2012-06-13 15:05:39

标签: c openmp

我对OpenMP很新,所以这可能有一个简单的答案,但我还没有找到它。

假设我有以下C代码并希望使用OpenMP并行化它。 A是一个对象数组,其中一些double值少于1个桶是一个链表的数组,append将一个指向对象的指针添加到一个链表的末尾。

#pragma omp for 
for (i = 0; i < n; ++i) {
    x = (int) (A[i].val * NUM_BUCKETS);
    append(&A[i], buckets[x]);
} 

问题是多个线程可能正在尝试一次将项目附加到给定的存储桶。我可以使附加声明变得至关重要。但是,在我的应用程序中,我可能有大约1000个桶,所以大多数时候线程将在不同的桶上运行。

有没有办法对存储桶的各个元素强制执行锁定?或者其他一些处理方式?

2 个答案:

答案 0 :(得分:8)

嗯,OpenMP不能自动为你做,但是它允许你创建自己的锁变量,你可以使用它来限制对数组元素的访问;例如,每个数组元素可以有一个锁:

#include <stdio.h>
#include <omp.h>


int main(int argc, char **argv)
{
    const int NITEMS=20;
    int array[NITEMS];
    omp_lock_t lock[NITEMS];

    for (int i=0; i<NITEMS; i++)
        omp_init_lock(&(lock[i]));

#pragma omp parallel for shared(array, lock) default(none)
     for (int i=0; i<NITEMS; i++) {
        int tid = omp_get_thread_num();
        int item = (i * 7) % NITEMS;

        omp_set_lock(&(lock[item]));
        array[item] = tid;    // only one thread in here at a time; others block at set_lock()
        omp_unset_lock(&(lock[item]));
    }

    for (int i=0; i<NITEMS; i++)
        printf("%3d ", array[i]);
    printf("\n");

    for (int i=0; i<NITEMS; i++)
        omp_destroy_lock(&(lock[i]));


    return 0;
}

或者,如果该级别的粒度超过您的需要,您可以阻止阵列的区域等。

答案 1 :(得分:2)

OpenMP不提供细粒度锁定。您可以准备新的列表元素,例如通过将其next指针设置为NULL并使用atomic来保护列表尾指针的更新。这与当前的OpenMP实现一样好。

当然,由于OpenMP使用底层操作系统线程原语,您可以使用后者提供的任何锁定,例如:为每个桶使用一组pthreads个互斥锁。缺点是它会创建不可移植的应用程序,但如果效率更重要,您可能愿意牺牲可移植性。