标签: openmp

通过openmp中的std容器进行迭代

我正在尝试使用openmp通过std :: set多线程循环.当我写下面的代码 -

    #pragma omp parallel for
    for (std::set<A>::const_iterator i = s.begin(); i != s.end(); ++i) {
            const A a = *i;
            operate(a);
    }
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

error: invalid type for iteration variable 'i'
error: invalid controlling predicate
error: invalid increment expression.
Run Code Online (Sandbox Code Playgroud)

是否有另一种正确的方法来使用openmp迭代std容器? 我知道我可以使用int i和迭代0s.size()迭代器或operator[]循环体,但这看起来不那么干净.

c++ stl openmp

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

为什么不允许使用未签名的OpenMP索引变量?

我的C++/OpenMP代码中有一个循环,如下所示:

#pragma omp parallel for
for(unsigned int i=0; i<count; i++)
{
    // do stuff
}
Run Code Online (Sandbox Code Playgroud)

当我编译它(使用Visual Studio 2005)时,我收到以下错误:

error C3016: 'i' : index variable in OpenMP 'for' statement must have signed integral type

我知道发生错误的原因i是因为是无符号而不是签名,而更改i为签名会删除此错误.我想知道的是为什么这是一个错误?为什么不允许使用无符号索引变量?查看此错误的MSDN页面没有提供任何线索.

c++ openmp

20
推荐指数
1
解决办法
4172
查看次数

OpenMP:堆数组性能不佳(堆栈数组工作正常)

我是一个相当有经验的OpenMP用户,但我遇到了一个令人费解的问题,我希望有人可以提供帮助.问题是,一个简单的哈希算法对堆栈分配的数组表现良好,但对堆上的数组表现不佳.

下面的示例使用i%M(i模数M)来计算相应阵列元素中的每个第M个整数.为简单起见,假设N = 1000000,M = 10.如果N%M == 0,那么结果应该是bins []的每个元素都等于N/M:

#pragma omp for
  for (int i=0; i<N; i++) 
    bins[ i%M ]++;
Run Code Online (Sandbox Code Playgroud)

数组bins []对每个线程都是私有的(我在之后对关键部分中所有线程的结果进行求和).

当在堆栈上分配bins []时,程序运行良好,性能与内核数量成比例缩放.

但是,如果bin []在堆上(指向bin []的指针在堆栈上),性能会急剧下降.这是一个重大问题!

我希望使用OpenMP将某些数据的binning(散列)并行化为堆数组,这是一个重大的性能影响.

绝对不是像所有线程试图写入同一内​​存区域那样愚蠢的东西.这是因为每个线程都有自己的bins []数组,结果对于堆栈和堆栈分配的bin都是正确的,并且单线程运行的性能没有差别.我使用GCC和英特尔C++编译器在不同的硬件(Intel Xeon和AMD Opteron)上重现了这个问题.所有测试都在Linux(Ubuntu和RedHat)上进行.

似乎没有理由将OpenMP的良好性能限制在堆栈数组中.

任何猜测?也许对线程的访问是通过Linux上的某种共享网关进行的?我该如何解决这个问题?

完整的程序如下:

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

int main(const int argc, const char* argv[])
{
  const int N=1024*1024*1024;
  const int M=4;
  double t1, t2;
  int checksum=0;

  printf("OpenMP threads: %d\n", omp_get_max_threads());

  //////////////////////////////////////////////////////////////////
  // Case 1: stack-allocated array
  t1=omp_get_wtime();
  checksum=0;
#pragma omp parallel
  { // Each openmp thread …
Run Code Online (Sandbox Code Playgroud)

heap performance stack multithreading openmp

20
推荐指数
1
解决办法
6275
查看次数

如何使用OpenMP并行化通过C++ std :: list的for循环?

我想使用OpenMP以并行方式遍历std :: list中的所有元素.循环应该能够改变列表的元素.有一个简单的解决方案吗?当迭代器是随机访问迭代器时,似乎OpenMP 3.0支持并行for循环,但不是其他.无论如何,我更喜欢使用OpenMP 2.0,因为我无法完全控制哪些编译器可供我使用.

如果我的容器是矢量,我可能会使用:

#pragma omp parallel for
for (auto it = v.begin(); it != v.end(); ++it) {
    it->process();
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以将列表复制到矢量中,执行循环,然后将所有内容复制回来.但是,如果可能的话,我想避免这种复杂性和开销.

c++ parallel-processing list openmp

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

OpenMP性能

首先,我知道经常会问这种[类型]问题,所以让我先说一下我尽可能多地阅读,但我仍然不知道这笔交易是什么.

我已经并行化了一个巨大的外部for循环.循环迭代次数各不相同,通常在20-150之间,但是循环体做了大量的工作,需要大量的局部密集线性代数例程(例如,代码是源的一部分,而不是外部依赖) .在循环体内有1000多个调用这些例程的调用,但它们都完全相互独立,所以我认为它将是并行性的主要候选者.循环代码是C++,但它调用了许多用C编写的子程序.

代码看起来像这样;

<declare and initialize shared variables here>
#ifdef _OPENMP
#pragma omp parallel for                            \
  private(....)\
  shared(....)              \
  firstprivate(....) schedule(runtime)
#endif
  for(tst = 0; tst < ntest; tst++) {

     // Lots of functionality (science!)
     // Calls to other deep functions which manipulate private variables only
     // Call to function which has 1000 loop iterations doing matrix manipulation
     // With no exaggeration, there are probably millions 
     // of for-loop iterations in this body, in the various functions …
Run Code Online (Sandbox Code Playgroud)

c c++ multithreading openmp

20
推荐指数
1
解决办法
6803
查看次数

如何使用g ++编译openmp

我有一个关于openmp编译的问题.

如下代码:

#include <iostream> 
#include <pthread.h>
#include <omp.h>
#include <semaphore.h>
#include <stack>
using namespace std;
sem_t empty,full;
stack<int> stk;
void produce(int i)
{
    {
    sem_wait(&empty);
            cout<<"produce "<<i*i<<endl;
            stk.push(i*i);
    sem_post(&full);
    }
}
void consume1(int &x)
{
    sem_wait(&full);
            int data=stk.top();
            stk.pop();
            x=data;
    sem_post(&empty);
}
void consume2()
{
    sem_wait(&full);
            int data=stk.top();
            stk.pop();
            cout<<"consume2 "<<data<<endl;
    sem_post(&empty);
}
int main()
{
    sem_init(&empty,0,1);
    sem_init(&full,0,0);
    pthread_t t1,t2,t3;
    omp_set_num_threads(3);
    int TID=0;
    #pragma omp parallel private(TID)
    {
            TID=omp_get_thread_num();
            if(TID==0)
            {
            cout<<"There are "<<omp_get_num_threads()<<" threads"<<endl;
            for(int i=0;i<5;i++)
                    produce(i);
            }
            else …
Run Code Online (Sandbox Code Playgroud)

c++ compilation g++ openmp

20
推荐指数
2
解决办法
7万
查看次数

openacc vs openmp&mpi的区别?

我想知道openacc和openmp之间的主要区别是什么.MPI,cuda和opencl怎么样?我理解openmp和mpi之间的区别,特别是关于共享和分布式内存的部分它们是否允许混合gpu-cpu处理设置?

cuda mpi openmp opencl openacc

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

从两个数组的点积测量内存带宽

两个数组的点积

for(int i=0; i<n; i++) {
    sum += x[i]*y[i];
}
Run Code Online (Sandbox Code Playgroud)

不重用数据,因此它应该是一个内存绑定操作.因此,我应该能够从点积测量内存带宽.

使用代码 为什么 - 矢量化 - 循环 - 没有性能改进 我的系统带宽为9.3 GB/s.但是,当我尝试使用点积计算带宽时,我获得单个线程的速率的两倍以及使用多个线程的速率超过三倍(我的系统有四个核心/八个超线程).这对我没有意义,因为内存绑定操作不应该受益于多个线程.以下代码的输出如下:

Xeon E5-1620, GCC 4.9.0, Linux kernel 3.13
dot 1 thread:      1.0 GB, sum 191054.81, time 4.98 s, 21.56 GB/s, 5.39 GFLOPS
dot_avx 1 thread   1.0 GB, sum 191043.33, time 5.16 s, 20.79 GB/s, 5.20 GFLOPS
dot_avx 2 threads: 1.0 GB, sum 191045.34, time 3.44 s, 31.24 GB/s, 7.81 GFLOPS
dot_avx 8 threads: 1.0 GB, sum 191043.34, time 3.26 …
Run Code Online (Sandbox Code Playgroud)

c++ memory bandwidth openmp avx

20
推荐指数
1
解决办法
2457
查看次数

是否可以使用openmp对数组进行减少?

OpenMP本身是否支持减少表示数组的变量?

这可能会像以下一样......

float* a = (float*) calloc(4*sizeof(float));
omp_set_num_threads(13);
#pragma omp parallel reduction(+:a)
for(i=0;i<4;i++){
   a[i] += 1;  // Thread-local copy of a incremented by something interesting
}
// a now contains [13 13 13 13]
Run Code Online (Sandbox Code Playgroud)

理想情况下,对于omp并行会有类似的东西,并且如果你有足够多的线程使它有意义,那么积累将通过二叉树发生.

c++ arrays openmp reduction

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

编写std :: vector vs plain数组的线程安全性

我已经在Stackoverflow上读到,没有一个STL容器对于写入是线程安全的.但这在实践中意味着什么?这是否意味着我应该将可写数据存储在普通数组中?

我希望并发调用std::vector::push_back(element)可能会导致数据结构不一致,因为它可能需要调整向量的大小.但是这样的情况呢,不涉及调整大小:

1)使用数组:

int data[n];
// initialize values here...

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    data[i] += func(i);
}
Run Code Online (Sandbox Code Playgroud)

2)使用`std :: vector``:

std::vector<int> data;
data.resize(n);
// initialize values here...

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    data[i] += func(i);
}
Run Code Online (Sandbox Code Playgroud)

第一个实现是否真的比第二个更好a)在线程安全方面和b)在性能方面?我更喜欢使用std :: vector,因为我对C风格的数组不太熟悉.

编辑:我删除了#pragma omp atomic update保护写.

c++ stl openmp thread-safety

19
推荐指数
2
解决办法
9067
查看次数