Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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 OpenMP:锁定对单个阵列元素的访问?_C_Openmp - Fatal编程技术网

C OpenMP:锁定对单个阵列元素的访问?

C OpenMP:锁定对单个阵列元素的访问?,c,openmp,C,Openmp,我对OpenMP相当陌生,因此这可能有一个简单的答案,但我一直无法找到它 假设我有下面的C代码,并希望使用OpenMP将其并行化。A是一个对象数组,其某些双精度值小于1。Bucket是一个链表数组,append将指向对象的指针添加到链表的末尾 #pragma omp for for (i = 0; i < n; ++i) { x = (int) (A[i].val * NUM_BUCKETS); append(&A[i], buckets[x]); } #pr

我对OpenMP相当陌生,因此这可能有一个简单的答案,但我一直无法找到它

假设我有下面的C代码,并希望使用OpenMP将其并行化。A是一个对象数组,其某些双精度值小于1。Bucket是一个链表数组,append将指向对象的指针添加到链表的末尾

#pragma omp for 
for (i = 0; i < n; ++i) {
    x = (int) (A[i].val * NUM_BUCKETS);
    append(&A[i], buckets[x]);
} 
#pragma omp for
对于(i=0;i
问题是,多个线程可能试图一次将项目附加到给定的bucket中。我可以让这个附加语句变得至关重要。然而,在我的应用程序中,我可能会有大约1000个存储桶,因此大部分时间线程将在不同的存储桶上运行


有没有办法对bucket的各个元素强制执行锁?或者其他处理方法?

OpenMP不提供细粒度锁定。您可以准备新的列表元素,例如,通过将其
next
指针设置为
NULL
,并使用
atomic
来保护列表尾部指针的更新。这是当前OpenMP实现所能达到的最佳效果


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

好吧,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;
}
#包括
#包括
int main(int argc,字符**argv)
{
常数int NITEMS=20;
int数组[NITEMS];
omp___t lock[NITEMS];

对于(int i=0;i@Jonathan如果NITEMS值事先不知道怎么办?似乎omp\U lock\U t lock[NITEMS]在编译代码之前需要一个常量…@Ash您只需分配一个动态大小的数组;
omp\U lock\U t*lock=(omp\U lock\U t*)malloc(NITEMS*sizeof(omp\U lock\U t));
等等。