我是使用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指令中是否允许使用复杂类型吗?
答案 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
,正如编译器告诉您的那样,它将无效。你想怎么表现呢?
你应该单独打印实部和虚部,或者如果你想要那么打印标准和阶段。