简体   繁体   English

如果在OpenMP中共享一个指针(和指向…的指针),将共享什么

[英]What will be shared if a pointer (and a pointer to a pointer to …) is shared in OpenMP

I have a structure 我有一个结构

typedef struct mystruct {
int* a;
float** b;
} mystruct;


mystruct* s = (mystruct*) calloc(1, sizeof(mystruct));
s->a  = (int*) calloc(100, sizeof(int));
s->b  = (float**) calloc(100, sizeof(float*));

for (int i=0; i<100; i++)
s->b[i]  = (float*) calloc(100, sizeof(float));

if I declare s to be shared in OpenMP as: 如果我声明s到OpenMP中被共享为:

#pragma omp parallel for  shared(s) schedule(auto)  

will all of the following variables in the memory be shared by all the threads: 内存中的以下所有变量将由所有线程共享:

  • the pointer a 指针a

  • the array pointed to by a , ie a[i], i=0,...,99 a指向的数组,即a[i], i=0,...,99

  • the pointer b 指针b

  • the array pointed to by b , ie b[i], i=0,...,99 b指向的数组,即b[i], i=0,...,99

  • the array pointed to by b[i], i=0,...,99 , ie b[i][j], j=0,...,99 b[i], i=0,...,99指向的数组,即b[i][j], j=0,...,99

What will be shared if a pointer (and a pointer to a pointer to …) is shared in OpenMP 如果在OpenMP中共享一个指针(和指向…的指针),将共享什么

Thanks! 谢谢!

Pointers are variables whose value is the address of a given memory cell (or the beginning of a group of cells). 指针是变量,其值是给定存储单元(或一组单元的开头)的地址。 Sharing a pointer shares the variable itself, ie the named memory location, where the address is being stored. 共享指针共享变量本身,即存储地址的命名存储位置。

Heap memory pointed to by pointers is always shared since nothing prevents you from accessing it from other threads through existing valid pointers. 指针指向的堆内存总是共享的,因为没有什么可以阻止您通过现有有效指针从其他线程访问它。

The following cases are possible: 以下情况是可能的:

  • shared(a) means that the pointer is shared by all threads. shared(a)表示指针被所有线程共享。 If any thread modifies a , eg executes a++ or assigns a new value to it, the pointer changes in all other threads too. 如果任何线程修改a ,如执行a++或新值,所有其他线程中的指针变化太大分配给它。 Since the value of the pointer is the same in all threads, they all can access the memory that it points to, ie the memory is shared; 由于指针的值在所有线程中都是相同的,因此它们都可以访问它指向的内存,即内存是共享的。

  • private(a) means that the pointer is private to each thread. private(a)表示指针是每个线程专用的。 Every threads gets its own uninitialised pointer variable. 每个线程都有自己的未初始化的指针变量。 If one thread assigns to a , the change is not visible in the other threads. 如果一个线程分配给a ,变化不是在其他线程可见。 Since the private copies are not initialised, the memory pointed by a outside the parallel region is not visible inside the threads unless there is another pointer to it or unless another mechanism to obtain a pointer to the memory exists; 由于私人副本没有初始化,由指向的存储器a ,除非有另一个指向它的指针或除非另一种机制来存储的存在是为了获得一个指针的平行区域的外侧不是线程内部可见;

  • firstprivate(a) means that the pointer is private to each thread but initially all private copies are set to the value of a before the parallel region. firstprivate(a)表示该指针是每个线程的私有指针,但是最初,所有私有副本均设置为并行区域之前的a值。 In that case each thread can modify the value of a and those modifications won't be visible by the other threads. 在这种情况下每个线程可以修改的值a和这些修改将不会被其他线程是可见的。 As long as all copies of a point somewhere within the memory that the original value of a points to, modifications to it done through the local copies of a are visible by all threads and hence the memory block is shared. 只要所有副本a该原始值点内的存储器某处a到,修改,以使其通过的本地拷贝进行点a都是由所有线程,因此存储块共享可见。

The private(a) case makes little sense and it is advisable that one uses block-local variables instead. private(a)案例意义不大,建议使用块局部变量代替。 That means, instead of 这意味着,而不是

int *p;

#pragma omp parallel private(p)
{
   ...
}

one is advised (for the sake of clarity) to use 建议(为清楚起见)使用

#pragma omp parallel
{
   int *p;
   ...
}

The data sharing clauses affect only the pointer variable and not the memory it points to. 数据共享子句仅影响指针变量, 而不影响其指向的内存。 For example, private(a) does not allocate a private copy of the heap memory originally pointed to by a : 例如, private(a) 不会分配最初由a指向的堆内存的私有副本:

int *a = malloc(10 * sizeof(int));

#pragma omp parallel private(a)
{
   a[1] = ... // <--- WRONG - no memory allocated automatically by OpenMP
}

An useful use case is one where each thread allocates its private heap memory: 一个有用的用例是每个线程分配其专用堆内存的情况:

#pragma omp parallel
{
    int *a = malloc(10 * sizeof(int));
    ...
    free(a);
}

The heap memory remains private to each thread unless its address is shared between the threads using a shared pointer. 除非使用共享指针在线程之间共享堆内存,否则堆内存对每个线程保持私有。

The same applies to pointer to pointers. 指向指针的指针也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM