标签: openmp

并行嵌套循环中的数据竞争

我有一个三重嵌套循环,我想并行化,但是,我遇到了数据争用问题。我很确定我需要以某种方式使用缩减,但我不太知道如何使用。

这是有问题的循环:

#pragma omp parallel for simd collapse(3)
    for (uint64 u = 0; u < nu; ++u) {
        for (uint64 e = 0; e < ne; ++e) {
            for (uint64 v = 0; v < nv; ++v) {
                uAT[u][e] += _uT[u][e][v] * wA[e][v];
            }
        }
    }

Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下,为什么这会导致数据竞争?我真的很想了解这一点,这样我将来就不会遇到这些问题。另外,这个循环可以并行吗?如果是这样,怎么办?

编辑:我怎么知道存在数据竞争?

这个循环应该完成的任务(并且它是串行完成的)是计算不连续伽辽金框架中函数的元素平均值。当我多次运行代码时,有时会得到不同的结果,尽管它应该总是产生相同的结果。产生的错误值总是小于应有的值,这就是为什么我假设某些值没有被添加。也许这张图可以更好地解释它:第三个单元格中的平均值显然是错误的(太小)。 第三个单元格中的平均值显然是错误的(太小)。

c simd openmp data-race

0
推荐指数
1
解决办法
239
查看次数

OpenMP:并行多重缩减

我有一些代码看起来像这样:

double r1 = 0.0, r2 = 0.0;

for (size_t i = 0; i < k; ++i) {
    r1 += reduction1(data1[i]);
}

for (size_t i = 0; i < k; ++i) {
    r2 += reduction2(data2[i]);
}
Run Code Online (Sandbox Code Playgroud)

这两个归约虽然运行相同次数的迭代,但运行在不同的路径和不同的数据集上。我想知道是否有办法并行运行这两种缩减。

奖励:如果两个循环运行不同次数的迭代怎么办?

编辑:就我而言,k它相当小,大部分工作都是在各个reduction函数内完成的。所以我的目标是并行执行尽可能多的归约函数。

c++ concurrency openmp c++20

0
推荐指数
1
解决办法
230
查看次数

OpenMP 线程未充分利用新机器上的 CPU 核心

我有一个多线程应用程序,可以并行解决巨大的矩阵。我最近更换了笔记本电脑,并开始在新笔记本电脑上出现一些奇怪的行为。旧笔记本电脑中的处理器是第 11 代英特尔(R) 酷睿(TM) i9-11950H,新笔记本电脑中的处理器是第 12 代英特尔(R) 酷睿(TM) i9-12900H。在旧笔记本电脑上运行我的多线程应用程序(使用 4 个线程)时,我看到这些线程占用了 4 个核心并充分利用它们,由于笔记本电脑有 8 个物理核心,总体 CPU 使用率约为 50%。请看下图: 在此输入图像描述

当使用相同(完全相同)的可执行二进制文件运行相同的应用程序时,我发现只有一个核心得到充分利用,其余核心的利用率约为 10%-20%,总体 CPU 使用率低于 15%。请看下图: 在此输入图像描述

有没有解释为什么相同的二进制文件在一台机器上运行而没有在另一台机器上运行?

笔记:

  • 我正在使用 OpenMP 启动线程
  • 我尝试将线程的优先级设置为高,但没有帮助

注意:在配备第 12 代英特尔(R) 酷睿(TM) i9-12900H 的笔记本电脑上,我从 BIOS 禁用了 E 核心,以确保线程仅分配给 P 核心,但这并没有解决问题。请看下面: 在此输入图像描述

从上图中我们可以看到,只有线程1充分利用了它的CPU。

以下是我启动线程的方式:

    CALL OMP_SET_NUM_THREADS(4)
    !$OMP PARALLEL DO PRIVATE(i)  
    DO i = 1, 4, 1
        CALL solve_axb_r_submat(n, A, line_A, X, B, flag, i, submatrix_number, Fkluunit(i))
    END DO
    !$OMP END PARALLEL DO
Run Code Online (Sandbox Code Playgroud)

上面的代码被调用超过 20000 次,因此每次迭代都会调用一个具有上面代码段的函数。我正在使用 Visual studio …

c++ multithreading fortran openmp

0
推荐指数
1
解决办法
946
查看次数

如何使用 OpenMP simd 对此循环进行矢量化?

我有以下代码,它接受输入 anx并填充输出向量y,我想使用 OpenMPsimd指令对其进行向量化:

for (size_t qi = 0; qi < nq; ++qi){
    const auto ii = face_indices[qi*3], jj = face_indices[qi*3+1], kk = face_indices[qi*3+2];
    y[ii] += x[kk] * fpl[ii] * fq[qi] * fpr[kk] - x[jj] * fpl[ii] * fq[qi] * fpr[jj];
    y[kk] += x[ii] * fpl[kk] * fq[qi] * fpr[ii] - x[jj] * fpl[kk] * fq[qi] * fpr[jj]; 
    y[jj] -= x[ii] * fpl[jj] * fq[qi] * fpr[ii] + x[kk] * fpl[jj] * fq[qi] * fpr[kk]; …
Run Code Online (Sandbox Code Playgroud)

c++ vectorization openmp

0
推荐指数
1
解决办法
95
查看次数

OpenMP是否支持异步操作?

我已经使用Javascript了一段时间,我喜欢它的异步操作,使用回调或承诺和期货.现在我需要使用OpenMP,但未能找到对这些功能的任何支持.

OpenMP是否支持回调和/或期货?

c future openmp promise async-await

-1
推荐指数
1
解决办法
439
查看次数

编译和链接中的 -fopenmp 标志

我有这个 openmp 代码

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

int main()
{
  #pragma omp parallel
  {
    fprintf(stderr, "thread %d\n", omp_get_thread_num());
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译、链接并使用-fopenmp

gcc-6 -std=c99 -Wall -Wextra -pedantic -fopenmp -Iinclude -c -o build/main.o src/main.c
gcc-6 -o bin/main  build/main.o  -fopenmp
Run Code Online (Sandbox Code Playgroud)

代码工作

$ ./bin/main 
thread 0
thread 1
thread 2
thread 3
Run Code Online (Sandbox Code Playgroud)

但当我只将标志放入链接时不要这样做

gcc-6 -std=c99 -Wall -Wextra -pedantic -Iinclude -c -o build/main.o src/main.c
src/main.c: In function 'main':
src/main.c:6:0: warning: ignoring #pragma omp parallel [-Wunknown-pragmas]
   #pragma omp parallel
gcc-6 -o bin/main  build/main.o …
Run Code Online (Sandbox Code Playgroud)

linker compilation openmp

-1
推荐指数
1
解决办法
3536
查看次数

Pi 计算给出了不正确的 OpenMP 结果

我刚接触 OpenMP,想知道这段代码有什么问题。它以串行方式工作。我正在使用 Ubuntu Linux 和 gfortran。

 !
    program test_rand
    
    use omp_lib
    implicit none

    integer, parameter :: num_threads =36
    integer*8,parameter :: nc = 1000000000
    integer*8 ncirc,ncircs(0:35)
    integer i,thread_num,istart,iend,ppt
    real*8 x,y,dist,pi
    integer,parameter :: seed = 864

        call srand(seed)
        do i=1,4
            ncircs(i)=0
            end do
            ncirc=0

            ppt=(nc+num_threads-1)/num_threads

            istart=1
            iend=nc
            thread_num=1
    !$ call omp_set_num_threads(num_threads)
    !$omp parallel default(none) private(istart,iend,thread_num,i, &
    !$omp dist,x,y,ncircs) shared(ppt,ncirc)
        !$ thread_num = omp_get_thread_num()
        !$ istart=thread_num*ppt+1
        !$ iend = min(nc,thread_num*ppt+ppt)
            print*,thread_num

            do i=istart,iend
            x=rand()
            y=rand()
            dist=sqrt((x-0.5)**2+(y-0.5)**2)
            if (dist.le.0.5) ncircs(thread_num)=ncircs(thread_num)+1
            end do

        !$omp critical …
Run Code Online (Sandbox Code Playgroud)

fortran openmp gfortran

-1
推荐指数
1
解决办法
107
查看次数

为什么我的简单编译会失败?

所以我只是从自制软件安装gcc,我有一个简单的代码:

#include <cmath>
#include <iostream>
#include <stdio.h>

int main()
{
    const int size = 256;
    double sinTable[size];

#pragma omp parallel for
    for(int n=0; n<size; ++n)
        sinTable[n] = std::sin(2 * M_PI * n / size);

#pragma omp parallel for
    for(int n=0; n<10; ++n)
    {
        printf(" %d", n);
    }
    printf(".\n");

    // the table is now initialized
}
Run Code Online (Sandbox Code Playgroud)

但是,当我编译时,我失败了:

    dhcp-18-189-47-44:openmp_code myname$ gcc-4.8 tmp2.cpp 
Undefined symbols for architecture x86_64:
  "std::ios_base::Init::Init()", referenced from:
      __static_initialization_and_destruction_0(int, int) in ccFbBrPl.o
  "std::ios_base::Init::~Init()", referenced from:
      __static_initialization_and_destruction_0(int, int) in ccFbBrPl.o
ld: …
Run Code Online (Sandbox Code Playgroud)

c++ openmp

-2
推荐指数
1
解决办法
83
查看次数

如何在OpenMP中将此for循环并行?

我试图通过添加"#pragma omp parallel for"来并行运行循环,但这对我如何并行这个循环没有任何建议?

#pragma omp parallel for
   for (p = split; *p != 0; p++) if (*p == ' ') *p = '0';
Run Code Online (Sandbox Code Playgroud)

c parallel-processing openmp

-2
推荐指数
1
解决办法
104
查看次数

openmp是否包含在c/c++中的stdio.h中?

我搜索了 openmp,发现有些人包含 omp.h,而其他人则不包含。它们只包含 stdio.h。

所以我的问题是: openmp 是否包含在 stdio.h 中,以便我们只包含它就可以使用 opemp ?

我认为旧的openmp(例如openmp2.0)需要与omp.h一起使用,但openmp3.0不需要如此。但我不确定...

c c++ openmp

-3
推荐指数
1
解决办法
217
查看次数