全局变量外部声明后的线程专用指令
Threadprivate directive after external declaration of global variables
>我有四个全局变量
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、工作区和设置作为参数传递给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
减速时,它可以编译并正常工作(减去由于所有线程使用相同的全局变量而存在的竞争条件(。
编辑:是的,全局变量是一种癌症,处理这个代码库非常令人沮丧。我没有编写底层代码,必须使用它来并行运行一个简单的测试用例。因此,完全不值得我花时间重构底层代码库。感谢马西米利亚诺阅读我所说的内容,而不是跳上全球变量仇恨列车。
所发生的事情很可能是将 threadprivate
子句插入而不是在声明全局变量的标头中的效果。
(线程本地存储(,而另一个翻译单元将其视为 TLS。这最终会产生链接错误。
解决方案是在声明这些全局变量的标头中插入 threadprivate
指令(当然,使用该标头在任何地方声明它们(。
全局变量是一种癌症。删除它们,您就不会有链接错误,而且您的代码实际上可能有点可维护。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 异常属于C++中的线程还是进程
- C++中的线程安全删除
- C++使用params创建线程函数会导致转换错误
- 类与私有变量的其他类之间的线程安全性
- CoInitialize()在单独的线程上崩溃而不返回
- c++中的线程池
- 线程之间的布尔停止信号
- 为什么std::async使用同一个线程运行函数
- 如何在 OpenMP 线程专用指令中使用对象的直接初始化
- 全局变量外部声明后的线程专用指令
- 在 OpenMP 中访问线程的专用内存