我是使用 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”的对象;调用将在运行时中止
如果我运行 a.out,我会在屏幕上看到一条“非法指令”消息。我试图找出发生了什么,但没有找到任何好的引用。有谁知道 OpenMP 指令中是否允许使用复杂类型?
最佳答案
错误在这里:
printf("Thread %d: c[%d]= %e\n",tid,i,c[i]);
printf
不知道(也没有办法知道)如何处理 std::complex
。使用 C++ 流操作输出复杂类型。
此外,为了避免并发问题,您需要先流式传输到线程本地缓冲区,然后才能写入标准输出,否则 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++ 不强制执行此操作,因此最好(始终)在首次使用时声明变量,即在并行部分内部声明。这样,它们也是线程私有(private)的。
关于c++ - 使用 OpenMP 的复杂类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9311742/