装配说明,以取代openmp关键区域

Pat*_*rik 4 assembly openmp critical-section

我有一个由openmp任务处理的元素数组.任务可能会在数组末尾添加新元素.当然,这些元素也必须处理,并可能产生新的项目.目前我正在使用此代码

int p;
#pragma omp critical
{
    p=l.n++;
}
Run Code Online (Sandbox Code Playgroud)

这只是在阵列末尾保留一个位置.类型l

struct list
{
    int n;
    double *e;
}
Run Code Online (Sandbox Code Playgroud)

并将p用作存储新元素的位置的索引.我想知道是否有办法在不使用关键区域的情况下执行此操作.是否有一个汇编指令复制一个值,然后原子地增加原始值?

代码将在nehalem cpu上执行,无需担心旧机器

Arj*_*kar 6

#pragma omp atomic capture
p = l.n++;
Run Code Online (Sandbox Code Playgroud)

如果硬件支持它,这应该在捕获值时使用原子增量.

#pragma omp atomic在这个问题中阅读更多信息:openMP,atomic vs critical?

这是英特尔的文档#pragma omp atomic.

我尝试编译一个最小的例子gcc -fopenmp -m32 -O2 -S:

int i, j;
void foo (void)
{
  #pragma omp atomic capture
  i = j++;
}
Run Code Online (Sandbox Code Playgroud)

我得到的是一个简单的原子'fetch and add',这就是我们想要的:

movl $1, %eax       # eax = 1
lock xaddl %eax, j  # atomic {swap (eax,j); j = eax + j;}
movl %eax, i        # i = eax
ret
Run Code Online (Sandbox Code Playgroud)