使用OpenMP的复杂类型

时间:2012-02-16 13:02:19

标签: c++ openmp complextype

我是使用OpenMP和C ++的新手。我正在做一个简单的函数,使用for循环加载两个数组。这些数组被定义为复杂的。

#include <omp.h>
#include <iostream>
#include <stdlib.h>
#include <complex>
#define CHUNKSIZE   10
#define N       100

using namespace std;

int main (int argc, char *argv[]) 
{
int nthreads, tid, i, chunk;
complex<double> a[N], b[N], c[N];

/* Some initializations */
for (i=0; i < N; i++)
    a[i].real() = b[i].real() = i * 1.0;
chunk = CHUNKSIZE;

#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid)
{
    tid = omp_get_thread_num();
    if (tid == 0)
    {
        nthreads = omp_get_num_threads();
        printf("Number of threads = %d\n", nthreads);
    }
    printf("Thread %d starting...\n",tid);

#pragma omp for schedule(dynamic,chunk)
    for (i=0; i<N; i++)
    {
        c[i] = a[i] + b[i];
        printf("Thread %d: c[%d]= %e\n",tid,i,c[i]);
    }

}  /* end of parallel section */

}

编译时,我收到此警告:

omp_complex.cpp:43:警告:无法通过'...'传递非POD类型'struct std :: complex'的对象; call将在运行时中止

如果我运行a.out,屏幕上会出现“非法指令”消息。我试图找出发生了什么,但我没有找到任何好的参考。有人知道OpenMP指令中是否允许使用复杂类型吗?

2 个答案:

答案 0 :(得分:4)

错误在于:

printf("Thread %d: c[%d]= %e\n",tid,i,c[i]);

printf不知道(并且无法知道)如何处理std::complex。使用C ++流操作输出复杂类型。

此外,为了避免并发问题,您需要在写入stdout之前流入线程本地缓冲区,否则C ++流语法会创建竞争条件。

我通常使用一个宏(但C ++ 11使用可变参数模板使这更容易):

#define THREAD_SAFE_OUT(out, message) \
    do { \
        std::ostringstream buffer; \
        buffer << message; \
        out << buffer.str(); \
    while (false)

…

THREAD_SAFE_OUT(std::cout, "Thread " << tid << ": c[" << i << "] = " << c[i]);

使用OpenMP时关于样式的一句话:

不要使用private指令。这只是需要在方法开头声明所有变量的语言的解决方法。由于C ++没有强制要求,因此最好(总是)在首次使用时声明变量,即并行部分。这样,它们也是线程私有的。

答案 1 :(得分:2)

您的问题是将std::complex<double>传递给printf,正如编译器告诉您的那样,它将无效。你想怎么表现呢?

你应该单独打印实部和虚部,或者如果你想要那么打印标准和阶段。