Yan*_*hou 5 tbb openmp thread-safety thread-local c++11
我有一个简单的问题,C++ 11 thread_local
可以与其他并行模型一起使用.
例如,我可以在使用OpenMP或Intel TBB并行执行任务时在函数内使用它.
大多数此类并行编程模型隐藏了更高级API背后的硬件线程.我的直觉是他们都必须将他们的任务调度程序映射到硬件线程中.我能指望C++ 11 thread_local
会产生预期的效果吗?
一个简单的例子是,
void func ()
{
static thread_local some_var = init_val;
#pragma omp parallel for [... clauses ...]
for (int i = 0; i < N; ++i) {
// access some_var somewhere within the loop
}
}
Run Code Online (Sandbox Code Playgroud)
我可以期望每个OpenMP线程都可以访问自己的副本some_var
吗?
我知道大多数并行编程模型都有自己的线程局部存储结构.但是,能够使用C++ 11 thread_local
(或编译器特定的关键字)是很好的.例如,考虑一下情况
// actually may implemented with a class with operator()
void func ()
{
static thread_local some_var;
// a quite complex function
}
void func_omp (int N)
{
#pragma omp for [... clauses ...]
for (int i = 0; i < N; ++i)
func();
}
void func_tbb (int N)
{
tbb::parallel_for(tbb::blocked_range<int>(0, N), func);
}
void func_select (int N)
{
// At runtime or at compile time, based which programming model is available,
// select to run func_omp or func_tbb
}
Run Code Online (Sandbox Code Playgroud)
这里的基本想法func
可能相当复杂.我想支持多个并行编程模型.如果我使用并行编程特定的线程局部构造,那么我实现了不同版本func
或至少部分版本.但是,如果我可以自由地使用C++ 11 thread_local
,那么除了func
我之外我只需要实现一些非常简单的函数.而对于大型项目的东西可以用模板写的更通用的版本进一步简化func_omp
,func_tbb
.但是,我不太确定这样做是否安全.
一方面,OpenMP规范有意省略了与其他编程范例的互操作性的任何规范,并且C++ 11线程与OpenMP的任何混合都是非标准的和特定于供应商的.另一方面,编译器(至少是GCC)倾向于使用相同的底层TLS机制来实现OpenMP #pragma omp threadprivate
,C++ 11 thread_local
和各种编译器特定的存储类__thread
.
例如,GCC完全在POSIX线程API之上实现其OpenMP运行时(libgomp),并threadprivate
通过将变量放在ELF TLS存储上来实现OpenMP .这与GNU的C++ 11实现互操作,该实现也使用POSIX线程并将thread_local
变量放在ELF TLS存储上.最终,这与使用__thread
关键字指定线程本地存储类和显式POSIX线程API调用的代码进行互操作.例如,以下代码:
int foo;
#pragma omp threadprivate(foo)
__thread int bar;
thread_local int baz;
int func(void)
{
return foo + bar + baz;
}
Run Code Online (Sandbox Code Playgroud)
编译成:
.globl foo
.section .tbss,"awT",@nobits
.align 4
.type foo, @object
.size foo, 4
foo:
.zero 4
.globl bar
.align 4
.type bar, @object
.size bar, 4
bar:
.zero 4
.globl baz
.align 4
.type baz, @object
.size baz, 4
baz:
.zero 4
movl %fs:foo@tpoff, %edx
movl %fs:bar@tpoff, %eax
addl %eax, %edx
movl %fs:baz@tpoff, %eax
Run Code Online (Sandbox Code Playgroud)
这里.tbss
ELF部分是线程本地BSS(未初始化数据).以相同的方式创建和访问所有三个变量.
目前,与其他编译器的互操作性较少受到关注.英特尔没有实施,thread_local
而Clang仍然缺少OpenMP支持.
归档时间: |
|
查看次数: |
1557 次 |
最近记录: |