GCC下无法使用threadprivate变量,Clang可正常运行的技术问题
OpenMP threadprivate变量在GCC下的编译错误问题
我正尝试优化以下并行执行代码,将Eigen向量evalInput设为threadprivate变量,使其可在线程内的迭代/任务间共享:
#pragma omp parallel for schedule(dynamic) for (int j = 0; j < input.rows(); ++j) { Eigen::VectorXf evalInput = input; // 修改evalInput的一个元素,计算后恢复 output.col(j) = factors * evalInput; }
尝试通过threadprivate和copyin让evalInput成为线程私有变量,但在GCC 13.2.1下报错,错误信息为error: ‘threadprivate’ ‘evalInput’ has incomplete type或error: ‘evalInput’ declared ‘threadprivate’ after first use,但相同代码在Clang中可正常运行。
简化测试用例(改用std::vector替代Eigen)
我准备了四个简化测试用例:
parallelBasic:基于模板Scalar的基础实现,可正常编译parallelOpt:添加threadprivate变量,报“不完整类型”错误parallelOptFloat:移除模板Scalar,报“首次使用后声明threadprivate”错误parallelVar:添加一个无用模板参数,可正常编译
编译命令
GCC编译失败:
g++ -o main -c main.cpp -Iinclude -fopenmp -lgomp
Clang编译可成功。
完整测试代码
#include <omp.h> #include <vector> template<typename Scalar> void parallelBasic(const std::vector<Scalar> &input, const std::vector<Scalar> &factors, std::vector<Scalar> &output) { #pragma omp parallel for schedule(dynamic) for (int j = 0; j < input.size(); ++j) { output[j] = factors[j] * input[j]; } } template<typename Scalar> void parallelOpt(const std::vector<Scalar> &input, const std::vector<Scalar> &factors, std::vector<Scalar> &output) { // 无法运行,报错“‘threadprivate’ ‘evalInput’ has incomplete type” static std::vector<Scalar> evalInput; #pragma omp threadprivate(evalInput) evalInput = input; #pragma omp parallel for schedule(dynamic) copyin(evalInput) for (int j = 0; j < input.size(); ++j) { output[j] = factors[j] * evalInput[j]; } } void parallelOptFloat(const std::vector<float> &input, const std::vector<float> &factors, std::vector<float> &output) { // 移除模板Scalar,仍无法运行,报错“‘evalInput’ declared ‘threadprivate’ after first use” static std::vector<float> evalInput; #pragma omp threadprivate(evalInput) evalInput = input; #pragma omp parallel for schedule(dynamic) copyin(evalInput) for (int j = 0; j < input.size(); ++j) { output[j] = factors[j] * evalInput[j]; } } template<typename Scalar> void parallelVar(const std::vector<float> &input, const std::vector<float> &factors, std::vector<float> &output, Scalar value) { // 可运行,仅添加了无用参数 static std::vector<float> evalInput; #pragma omp threadprivate(evalInput) evalInput = input; #pragma omp parallel for schedule(dynamic) copyin(evalInput) for (int j = 0; j < input.size(); ++j) { output[j] = factors[j] * evalInput[j]; } } int main () { omp_set_dynamic(0); std::vector<float> input(100), factors(100), output(100); parallelBasic<float>(input, factors, output); //parallelOpt<float>(input, factors, output); //parallelOptFloat(input, factors, output); parallelVar(input, factors, output, 1); return 0; }
恳请各位提供帮助。
内容的提问来源于stack exchange,提问作者Seneral
相关产品推荐
相关产品推荐

