我有四个全局变量
extern Vars vars;
extern Params params;
extern Workspace work;
extern Settings settings
我正在尝试使用以下方式将线程设为私有:
#pragma omp threadprivate(vars,params,work,settings)
然后我调用这个函数:
void parallelSolver(void *handle, Params *paramsIn, double* data, int dataNum){
int i;
#pragma omp parallel for
for (i = 0; i < dataNum; i++) { // Main control loop.
Params paramsOW = load_data(*paramsIn, data, i);
csolve(paramsOW);
}
}
将每个单独运行的数据加载到paramsOW,然后调用:
void csolve(Params paramsIn){
set_defaults(); // Set basic algorithm parameters.
setup_indexing();
params = paramsIn;
printValues(params);
// Solve our problem at high speed!
long num_iters = solve();
// Recommended: check work.converged == 1.
// use_solution(vars);
}
调用solve()
调用许多使用这些全局变量的函数。我宁愿能够将Vars,Params,Workspace和Settings作为参数传递给solve()
,但编写代码的方式,我必须遵循的范例是,它使我们成为这些全局变量。我在尝试编译此代码时遇到的错误是:
$ gcc -fopenmp -shared -Wl,-soname,runSolverParalle -o runSolverParallel.so -fPIC runSolverParallel.c solver.c ldl.c matrix_support.c
/usr/bin/ld: work: TLS reference in /tmp/cc7BbGwf.o mismatches non-TLS reference in /tmp/ccbUwz29.o
/tmp/ccbUwz29.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
注意我正在将其编译为共享对象,因为我使用cython和python代码发送parallelSolver
实例化它的数据。当我消除threadprivate
减速时,它编译并正常工作(减去由于所有线程使用相同的全局变量而存在的竞争条件)。
答案 0 :(得分:4)
发生的事情很可能是插入threadprivate
子句不在声明全局变量的标头内部的效果。
实际上,一个翻译单元将变量视为非TLS (线程本地存储),而另一个翻译单元将其视为 TLS 。这最终会产生链接错误。
解决方案是在声明那些全局变量的标题中插入threadprivate
指令(当然要使用该标头在任何地方声明它们)。
答案 1 :(得分:-1)
全球变量是一种癌症。消除它们并且你不会有链接错误,而且你的代码可能实际上有点可维护。