标签: openmp

OpenMP num_threads(1)的执行速度比没有OpenMP的速度快

我在各种情况下运行我的代码,这导致我认为是奇怪的行为.我的测试是在带HT的双核intel xeon处理器上进行的.

没有OpenMP'#pragma'语句,总运行时间= 507秒

使用指定1核的OpenMP'#pragma'语句,总运行时间= 117秒

使用指定2核的OpenMP'#pragma'语句,总运行时间= 150秒

使用指定3核的OpenMP'#pragma'语句,总运行时间= 157秒

使用指定4核的OpenMP'#pragma'语句,总运行时间= 144秒

我想我无法弄清楚为什么注释掉我的openmp行会使程序在没有openmp的1个线程和1个带有openmp的线程之间变慢.

我正在改变的是:

//#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1) schedule(guided)

and...

#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1,2,3,4) schedule(guided)
Run Code Online (Sandbox Code Playgroud)

无论如何,如果有人知道为什么会这样,请告诉我!

谢谢你的帮助,

布雷特

编辑:我将在这里解决一些评论

我正在使用num_threads(1),num_threads(2)等.

经过进一步调查,结果表明,根据代码中是否包含"schedule(guided)"行,我的结果不一致.

- 当我使用计划(指导)行时,无论线程数如何,我都会生成最快的解决方案. - 当我使用默认调度程序时,我的结果明显变慢并且不同的值 - 随着线程增加而没有获得计划(指导)改进 - 没有计划(指导)我通过添加线程获得改进

我想我还没有找到一个足够好的描述(导引)对我做什么,我明白它试图分割循环,以便最先进行时间密集的迭代,这应该具有最小的影响一个线程等待其他线程完成迭代的时间.

似乎对于我的~900迭代循环,当我使用schedule(被引导)时,我只处理~200次迭代,其中没有时间表(被引导)我正在处理所有900次迭代.有什么想法吗?

c c++ multithreading openmp

10
推荐指数
1
解决办法
5567
查看次数

在多线程环境中的Malloc性能

我一直在使用openmp框架进行一些实验,发现了一些奇怪的结果,我不知道我知道如何解释.

我的目标是创建这个巨大的矩阵,然后用值填充它.为了从多线程环境中获得性能,我将代码的某些部分作为并行循环.我在一台配有2个四核xeon处理器的机器上运行它,所以我可以安全地在那里放置8个并发线程.

一切都按预期工作,但由于某种原因,实际分配矩阵行的for循环在仅运行3个线程时具有奇怪的峰值性能.从那以后,添加更多线程只会让我的循环花费更长时间.8个线程实际上只需要一个线程就可以获得更多时间.

这是我的并行循环:

 int width = 11;
 int height = 39916800;
 vector<vector<int> > matrix;
 matrix.resize(height);    
 #pragma omp parallel shared(matrix,width,height) private(i) num_threads(3)
 {
   #pragma omp for schedule(dynamic,chunk)
   for(i = 0; i < height; i++){
     matrix[i].resize(width);
   }
 } /* End of parallel block */
Run Code Online (Sandbox Code Playgroud)

这让我想知道:在多线程环境中调用malloc(我想是矢量模板类的resize方法实际调用的)时是否存在已知的性能问题?我在一个多线程环境中发现了一些关于释放堆空间性能损失的文章,但没有具体说明在这种情况下分配新空间.

举一个例子,我将下面的图表显示循环完成所需的时间作为分配循环的线程数的函数,以及一个只读取来自这个巨大矩阵的数据的正常循环稍后的.

并行区域1,其中有分配

并行区域2,没有分配

两次使用gettimeofday函数测量并且似乎在不同的执行实例中返回非常相似和准确的结果.那么,任何人都有一个很好的解释?

malloc performance multithreading openmp

10
推荐指数
1
解决办法
3625
查看次数

优化和为什么openmp比顺序方式慢得多?

我是OpenMp编程的新手.我写了一个简单的c程序来将矩阵与向量相乘.不幸的是,通过比较执行时间,我发现OpenMP比Sequential方式慢得多.

这是我的代码(这里的矩阵是N*N int,vector是N int,结果是N long long):

#pragma omp parallel for private(i,j) shared(matrix,vector,result,m_size)
for(i=0;i<m_size;i++)
{  
  for(j=0;j<m_size;j++)
  {  
    result[i]+=matrix[i][j]*vector[j];
  }
}
Run Code Online (Sandbox Code Playgroud)

这是顺序方式的代码:

for (i=0;i<m_size;i++)
        for(j=0;j<m_size;j++)
            result[i] += matrix[i][j] * vector[j];
Run Code Online (Sandbox Code Playgroud)

当我使用999x999矩阵和999向量尝试这两个实现时,执行时间为:

顺序:5439 ms并行:11120 ms

我真的不明白为什么OpenMP比顺序算法慢得多(慢2倍!)任何人都可以解决我的问题?

c performance vector matrix openmp

10
推荐指数
2
解决办法
1万
查看次数

使用数组避免OpenMP中的虚假共享

我已经开始学习如何使用OpenMP作为大学课程的一部分.作为实验练习,我们获得了一个需要并行化的系列程序.

我们首先了解了False Sharing的危险性,尤其是在为循环并行更新数组时.

但是,我发现很难将以下代码片段转换为可并行执行的任务,而不会导致错误共享:

int ii,kk;

double *uk = malloc(sizeof(double) * NX);
double *ukp1 = malloc(sizeof(double) * NX);
double *temp;

double dx = 1.0/(double)NX;
double dt = 0.5*dx*dx;

// Initialise both arrays with values
init(uk, ukp1);

for(kk=0; kk<NSTEPS; kk++) {
   for(ii=1; ii<NX-1; ii++) {
      ukp1[ii] = uk[ii] + (dt/(dx*dx))*(uk[ii+1]-2*uk[ii]+uk[ii-1]);
   }

   temp = ukp1;
   ukp1 = uk;
   uk = temp;
   printValues(uk,kk);
}
Run Code Online (Sandbox Code Playgroud)

我的第一反应是尝试分享ukp1:

for(kk=0; kk<NSTEPS; kk++) {
   #pragma omp parallel for shared(ukp1)
   for(ii=1; ii<NX-1; ii++) {
      ukp1[ii] …
Run Code Online (Sandbox Code Playgroud)

c openmp false-sharing

10
推荐指数
2
解决办法
1万
查看次数

与SSE并行的前缀(累计)总和

我正在寻找有关如何与SSE进行并行前缀和的一些建议.我有兴趣在一系列整数,浮点数或双精度数上执行此操作.

我想出了两个解决方案.一个特例和一般情况.在这两种情况下,解决方案在与OpenMP并行的两次传递中在阵列上运行.对于特殊情况,我在两次传球时使用SSE.对于一般情况,我只在第二遍使用它.

我的主要问题是如何在一般案例的第一遍中使用SSE? 以下链接simd-prefix-sum-on-intel-cpu显示字节的改进,但不是32位数据类型.

特殊情况称为特殊情况的原因是它要求数组采用特殊格式.例如,假设a浮点数组中只有16个元素.然后,如果数组像这样重新排列(结构数组结构):

a[0] a[1] ...a[15] -> a[0] a[4] a[8] a[12] a[1] a[5] a[9] a[13]...a[3] a[7] a[11] a[15]
Run Code Online (Sandbox Code Playgroud)

SSE垂直总和可用于两个通道.但是,只有当数组已经采用特殊格式并且输出可以以特殊格式使用时,这才有效.否则,必须在输入和输出上进行昂贵的重新排列,这将使其比一般情况慢得多.

也许我应该考虑一个不同的前缀和算法(例如二叉树)?

一般情况的代码:

void prefix_sum_omp_sse(double a[], double s[], int n) {
    double *suma;
    #pragma omp parallel
    {
        const int ithread = omp_get_thread_num();
        const int nthreads = omp_get_num_threads();
        #pragma omp single
        {
            suma = new double[nthreads + 1];
            suma[0] = 0;
        }
        double sum = 0;
        #pragma omp for schedule(static) nowait //first parallel pass
        for (int i …
Run Code Online (Sandbox Code Playgroud)

c sse sum openmp

10
推荐指数
1
解决办法
3633
查看次数

链接OpenMP与-fopenmp和-lgomp之间的区别

过去几天我一直在努力解决一个奇怪的问题.我们使用GCC 4.8创建了一些库,它们静态地链接了一些依赖项 - 例如.log4cplus或者提升.对于这些库,我们使用boost-python创建了Python绑定.

每次这样的库使用TLS(就像log4cplus在它的静态初始化中做的那样,或stdlibc ++在抛出异常时也会这样 - 不仅在初始化阶段)整个事件在段错误中崩溃 - 并且每次线程局部变量的地址都为0 .

我尝试了重新编译等所有内容,确保使用-fPIC,确保使用-tls-model = global-dynamic等.没有成功.然后今天我发现这些崩溃的原因是我们链接OpenMP的方式.我们使用"-lgomp"而不是仅仅使用"-fopenmp"来完成此操作.因为我改变了这一切一切正常 - 没有崩溃,没有什么.精细!

但我真的想知道问题的原因是什么.那么在OpenMP中链接这两种可能性有什么区别?

我们在这里安装了一台CentOS 5机器,我们在/ opt/local/gcc48中安装了GCC-4.8,我们也确信来自/ opt/local/gcc48的libgomp和libstdc ++一起使用(DL_DEBUG)用过的).

有任何想法吗?在谷歌上没有找到任何东西 - 或者我使用了错误的关键字:)

c++ openmp dlopen static-linking

10
推荐指数
1
解决办法
2万
查看次数

缺少: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES

我在 Mac OSX 上使用 OpenMP 编译项目时遇到了困难。错误是:

CMake Error at /usr/local/Cellar/cmake/3.10.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
Could NOT find OpenMP_C (missing: OpenMP_C_FLAGS OpenMP_C_LIB_NAMES)
Call stack most recent call first) 
/usr/local/Cellar/cmake/3.10.2/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
/usr/local/Cellar/cmake/3.10.2/share/cmake/Modules/FindOpenMP.cmake:447 (find_package_handle_standard_args)
libRORPO/CMakeLists.txt:7 (find_package)
Run Code Online (Sandbox Code Playgroud)

项目中与 OpenMP 搜索相关的 CMakeLists 文件如下:

# RORPO Lib

project(libRORPO)
cmake_minimum_required(VERSION 2.8)

# FIND OPENMP
find_package( OpenMP REQUIRED)
if(OPENMP_FOUND)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} 
         ${OpenMP_EXE_LINKER_FLAGS}")
endif()

# ADD FILES
file(GLOB_RECURSE RORPO_HEADERS *.hpp *.h)
file(GLOB_RECURSE RORPO_SOURCES *.c)

add_library(RORPO ${LIB_TYPE} ${RORPO_SOURCES} ${RORPO_HEADERS})

install( FILES ${RORPO_HEADERS} DESTINATION include/libRORPO)
install( TARGETS RORPO …
Run Code Online (Sandbox Code Playgroud)

c++ macos cmake openmp

10
推荐指数
4
解决办法
3万
查看次数

声明自己(*this)私有的类以避免竞争条件/在gcc中放弃使用threadprivate

我想避免并行代码中的竞争条件.问题是我的类包含几个全局变量,让我们说一个x简单的变量,以及一个for我希望并行的循环.实际的代码还有一个方法,它接受一个类的指针,在本例中为自身,作为参数,访问更多的全局变量.因此,threadprivate.使用OpenMP 创建整个实例可能是有意义的.MWE是

#include <iostream>
#include <omp.h>
class lotswork {
public:
    int x;
    int f[10];

    lotswork(int i = 0) { x = i; };

    void addInt(int y) { x = x + y; }

    void carryout(){

        #pragma omp parallel for
        for (int n = 0; n < 10; ++n) {
            this->addInt(n);
            f[n] = x;
        }
        for(int j=0;j<10;++j){
            std::cout << " array at " << j << " = " << f[j] << std::endl;
        }
        std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ gcc openmp

10
推荐指数
1
解决办法
336
查看次数

指针是否在OpenMP并行部分中是私有的?

我已经将OpenMP添加到现有代码库中,以便并行化for循环.在parallel for区域范围内创建了几个变量,包括一个指针:

#pragma omp parallel for
for (int i = 0; i < n; i++){
    [....]
    Model *lm;
    lm->myfunc();
    lm->anotherfunc();
    [....]
}
Run Code Online (Sandbox Code Playgroud)

在结果输出文件中,我注意到不一致,可能是由竞争条件引起的.我最终通过使用一个解决了竞争条件omp critical.我的问题仍然存在:lm每个线程都是私有的,还是共享的?

c++ parallel-processing multithreading openmp

9
推荐指数
1
解决办法
3551
查看次数

迭代与Cython并行的列表

如何在Cython中的(Python)列表上并行迭代?

考虑以下简单功能:

def sumList():
    cdef int n = 1000
    cdef int sum = 0

    ls = [i for i in range(n)]

    cdef Py_ssize_t i
    for i in prange(n, nogil=True):
        sum += ls[i]

    return sum
Run Code Online (Sandbox Code Playgroud)

这会产生很多编译器错误,因为没有GIL的并行部分显然无法与任何Python对象一起使用:

Error compiling Cython file:
------------------------------------------------------------
...

    ls = [i for i in range(n)]

    cdef Py_ssize_t i
    for i in prange(n, nogil=True):
        sum += ls[i]
     ^
------------------------------------------------------------

src/parallel.pyx:42:6: Coercion from Python not allowed without the GIL

Error compiling Cython file:
------------------------------------------------------------
...

    ls = [i for …
Run Code Online (Sandbox Code Playgroud)

python parallel-processing openmp cython

9
推荐指数
1
解决办法
7382
查看次数