标签: openmp

并行任务使用boost :: thread比使用ppl或OpenMP获得更好的性能

我有一个可以并行化的C++程序.我正在使用Visual Studio 2010,32位编译.

简而言之,该计划的结构如下

#define num_iterations 64 //some number

struct result
{ 
    //some stuff
}

result best_result=initial_bad_result;

for(i=0; i<many_times; i++)
{ 
    result *results[num_iterations];


    for(j=0; j<num_iterations; j++)
    {
        some_computations(results+j);
    }

    // update best_result; 
}
Run Code Online (Sandbox Code Playgroud)

由于每个some_computations()都是独立的(读取了一些全局变量,但没有修改全局变量),我并行化了内部for循环.

我的第一次尝试是使用boost :: thread,

 thread_group group;
 for(j=0; j<num_iterations; j++)
 {
     group.create_thread(boost::bind(&some_computation, this, result+j));
 } 
 group.join_all();
Run Code Online (Sandbox Code Playgroud)

结果很好,但我决定尝试更多.

我试过OpenMP

 #pragma omp parallel for
 for(j=0; j<num_iterations; j++)
 {
     some_computations(results+j);
 } 
Run Code Online (Sandbox Code Playgroud)

结果比boost::thread那些更差.

然后我尝试了ppl库并使用parallel_for():

 Concurrency::parallel_for(0,num_iterations, [=](int j) { …
Run Code Online (Sandbox Code Playgroud)

c++ openmp boost-thread ppl

11
推荐指数
1
解决办法
9822
查看次数

为什么我的线程有时会"口吃"?

我正在尝试编写一些多线程代码来从DAQ设备读取并同时渲染捕获的信号:

std::atomic <bool> rendering (false);
auto render = [&rendering, &display, &signal] (void)
    {
        while (not rendering)
            {std::this_thread::yield ();};
        do {display.draw (signal);}
            while (display.rendering ()); // returns false when user quits
        rendering = false;
    };
auto capture = [&rendering, &daq] (void)
    {
        for (int i = daq.read_frequency (); i --> 0;)
            daq.record (); // fill the buffer before displaying the signal
        rendering = true;
        do {daq.record ();} 
            while (rendering);
        daq.stop ();
    };
std::thread rendering_thread (render);
std::thread capturing_thread (capture);

rendering_thread.join ();
capturing_thread.join …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading openmp c++11

11
推荐指数
1
解决办法
630
查看次数

如何避免嵌套循环中openMP的开销

我有两个版本的代码产生相同的结果,我试图只并行化嵌套for循环的内部循环.我没有得到太多的加速,但我没想到1对1,因为我只想并行化内循环.

我的主要问题是为什么这两个版本的运行时间相似?不是第二个版本的fork线程只有一次并且避免了i在第一个版本中每次迭代时启动新线程的开销吗?

第一个版本的代码在外部循环的每次迭代中启动线程,如下所示:

for(i=0; i<2000000; i++){
  sum = 0;
  #pragma omp parallel for private(j) reduction(+:sum)
  for(j=0; j<1000; j++){
    sum += 1;
  }
  final += sum;
}
printf("final=%d\n",final/2000000);
Run Code Online (Sandbox Code Playgroud)

使用此输出和运行时:

OMP_NUM_THREADS = 1

final=1000
real    0m5.847s
user    0m5.628s
sys     0m0.212s
Run Code Online (Sandbox Code Playgroud)

OMP_NUM_THREADS = 4

final=1000
real    0m4.017s
user    0m15.612s
sys     0m0.336s
Run Code Online (Sandbox Code Playgroud)

第二个版本的代码在外部循环之前启动一次线程(?)并像这样并行化内部循环:

#pragma omp parallel private(i,j)
for(i=0; i<2000000; i++){
  sum = 0;
  #pragma omp barrier
  #pragma omp for reduction(+:sum)
  for(j=0; j<1000; j++){
    sum += 1;
  }
  #pragma omp single …
Run Code Online (Sandbox Code Playgroud)

c openmp

11
推荐指数
1
解决办法
857
查看次数

OpenMP,R和MacOS

所以当我加载它时,我尝试运行一个名为BTYDplus的包我得到了这个警告

This data.table install has not detected OpenMP support. It will work but slower in single threaded mode.

我可以运行它没有OpenMP的,但它是非常缓慢的,所以我想通过下面这个教程安装的OpenMP http://thecoatlessprofessor.com/programming/openmp-in-r-on-os-x/ 但我在卡住Enabling R to Compile Code with OpenMP on OS X部分明确当我试图跑vim ~/.R/Makevars/.结果是"~/.R/Makevars/" Illegal file name.

关于如何告诉R使用GCC的任何建议?

gcc r openmp clang

11
推荐指数
1
解决办法
1493
查看次数

为什么这个随机数生成器不是线程安全的?

我正在使用rand()函数生成0,1之间的伪随机数用于模拟目的,但是当我决定使我的C++代码并行运行时(通过OpenMP),我注意到rand()它不是线程安全的,也不是很均匀.

所以我转而使用在其他问题的许多答案中提出的(所谓的)更均匀的生成器.看起来像这样

double rnd(const double & min, const double & max) {
    static thread_local mt19937* generator = nullptr;
    if (!generator) generator = new mt19937(clock() + omp_get_thread_num());
    uniform_real_distribution<double> distribution(min, max);
    return fabs(distribution(*generator));
}
Run Code Online (Sandbox Code Playgroud)

但是我在我模拟的原始问题中看到了许多科学错误.既反对结果rand()也反对常识的问题.

所以我编写了一个代码,用这个函数生成500k随机数,计算它们的平均值并做200次并绘制结果.

double SUM=0;
for(r=0; r<=10; r+=0.05){   
    #pragma omp parallel for ordered schedule(static)
    for(w=1; w<=500000; w++){   
        double a;
        a=rnd(0,1);
        SUM=SUM+a;
    } 
    SUM=SUM/w_max;
    ft<<r<<'\t'<<SUM<<'\n';
    SUM=0;
}   
Run Code Online (Sandbox Code Playgroud)

我们知道如果不是500k,我可以无限次地做它,它应该是一个值为0.5的简单线.但是有了500k,我们的波动将在0.5左右.

使用单个线程运行代码时,结果是可以接受的:

在此输入图像描述

但这是2个线程的结果:

在此输入图像描述

3个主题:

在此输入图像描述

4个主题:

在此输入图像描述

我现在没有我的8线程CPU,但结果甚至值得.

正如你所看到的,它们都不均匀,并且在平均值附近波动很大.

这个伪随机生成器线程也不安全吗?

或者我在某个地方犯了错误?

c++ random multithreading openmp

11
推荐指数
2
解决办法
566
查看次数

C++17 并行算法 vs tbb 并行 vs openmp 性能

由于 c++17 std 库支持并行算法,我认为它是我们的首选,但在与tbband比较后openmp,我改变了主意,我发现 std 库要慢得多。

通过这个帖子,我想请教一下我是否应该放弃标准库的并行算法,而使用tbbor 的专业建议openmp,谢谢!

环境:

  • Mac OSX,Catalina 10.15.7
  • GNU g++-10

基准代码:

#include <algorithm>
#include <cmath>
#include <chrono>
#include <execution>
#include <iostream>
#include <tbb/parallel_for.h>
#include <vector>

const size_t N = 1000000;

double std_for() {
  auto values = std::vector<double>(N);

  size_t n_par = 5lu;
  auto indices = std::vector<size_t>(n_par);
  std::iota(indices.begin(), indices.end(), 0lu);
  size_t stride = static_cast<size_t>(N / n_par) + 1;

  std::for_each(
      std::execution::par,
      indices.begin(),
      indices.end(),
      [&](size_t index) {
        int begin = index * …
Run Code Online (Sandbox Code Playgroud)

c++ parallel-processing tbb openmp c++17

11
推荐指数
1
解决办法
634
查看次数

OpenMP和STL风格

我正在尝试使用openMP并行化我的程序.该程序大量使用STL迭代器.这是说,是的OpenMP 3.0可以解决这个问题:

std::vector<int> N(2*N_max+1);

std::vector<int>::const_iterator n,m;
#pragma omp parallel for
for (n=N.begin(); n!=N.end(); ++n){
     //Task to be in parallel
};
Run Code Online (Sandbox Code Playgroud)

但是我收到以下错误:

error: invalid controlling predicate
Run Code Online (Sandbox Code Playgroud)

我正在使用gcc 4.5.0,(4.4.0中实现的openMP3),我的构建字符串是:

g++  -O0 -g3 -Wall -c -fmessage-length=0 -fopenmp -MMD -MP  
Run Code Online (Sandbox Code Playgroud)

c++ for-loop stl openmp

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

多维嵌套OpenMP循环

在OpenMP中并行化多维尴尬并行循环的正确方法是什么?维度的数量在编译时是已知的,但是哪个维度是大的.他们中的任何一个可能是一,二或一百万.当然我不希望N omp parallel是一个N维循环......

思考:

  • 问题在概念上很简单.只有最外层的"大"循环需要并行化,但循环维度在编译时是未知的并且可能会发生变化.

  • 将动态设置omp_set_num_threads(1)#pragma omp for schedule(static, huge_number)使某些环路并行化无操作?这会产生不良的副作用/开销吗?感觉像一个kludge.

  • OpenMP规范(2.10,A.38,A.39)讲述整合及不符合要求的嵌套并行之间的差异,但没有提出解决这个问题的最好的办法.

  • 可以重新排序循环,但可能会导致大量缓存未命中.展开是可能的,但不是重要的.还有另外一种方法吗?

这是我要并行化的内容:

for(i0=0; i0<n[0]; i0++) {
  for(i1=0; i1<n[1]; i1++) {
    ...
       for(iN=0; iN<n[N]; iN++) {
         <embarrasingly parallel operations>
       }
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

c parallel-processing openmp nested-loops

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

OpenMP - 在并行代码中运行并行代码

我有一个compute()使用OpenMP在其内部并行化矩阵乘法的函数

#pragma omp parallel for
Run Code Online (Sandbox Code Playgroud)

这个函数在循环中被多次调用 - 我想并行运行.在其他并行代码中运行并行代码会有任何问题吗?

这是在Ubuntu上编译的c ++.

c++ parallel-processing openmp

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

使用OpenMP和Eigen会导致无限循环/死锁

当我尝试使用OpenMP并行化一些循环时,我正在解决一个更大的问题并遇到了一个bug.我用下面的一些更简单的代码重现了这个问题,这些代码模仿了我自己的代码.

问题是,当我运行程序时,它将随机进入某种无限循环/死锁(CPU为100%,但没有做任何事情).从我的测试中可以看出,其中一个线程试图计算矩阵矩阵产品,但由于某种原因从未完成.

我知道如果启用OpenMP,Eigen将使用OpenMP并行化矩阵 - 矩阵产品.我还在这之外添加另一个并行循环.但是,如果我通过定义EIGEN_DONT_PARALLELIZE禁用Eigen的并行化,则仍会出现此错误.

我在MacOS 10.6.8上使用gcc版本4.6.0 20101127和Eigen 3.0.4.

我无法弄清楚会出现什么问题......

#include <iostream>
#include <Eigen/Core>

using namespace std;
using namespace Eigen;

MatrixXd Test(MatrixXd const& F, MatrixXd const& G)
{
  MatrixXd H(F.rows(), G.cols());
  H.noalias() = F*G;

  return H;
}

int main()
{
  MatrixXd F = MatrixXd::Random(2,2);
  MatrixXd G = MatrixXd::Random(2,2);

  #pragma omp parallel for
  for (unsigned int i = 0; i < 10000; ++i)
    MatrixXd H = Test(F,G);

  cout << "Done!" << endl;
}
Run Code Online (Sandbox Code Playgroud)

c++ openmp eigen

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

标签 统计

openmp ×10

c++ ×7

parallel-processing ×3

c ×2

multithreading ×2

boost-thread ×1

c++11 ×1

c++17 ×1

clang ×1

eigen ×1

for-loop ×1

gcc ×1

nested-loops ×1

ppl ×1

r ×1

random ×1

stl ×1

tbb ×1