注意:这不是这个问题的重复。
给定一个与 TBB 并行的复杂软件,我如何完全关闭线程?我知道task_scheduler_init:
int nthreads = tbb::task_scheduler_init::default_num_threads();
const char* cnthreads = getenv("TBB_NUM_THREADS");
if (cnthreads) nthreads = std::max(1, atoi(cnthreads));
tbb::task_arena arena(nthreads, 1);
tbb::task_scheduler_init init(nthreads);
Run Code Online (Sandbox Code Playgroud)
但是,此解决方案(与此相关)不会关闭线程。TBB 仍然会创建大量线程,nthreads只是使其中一些线程未被使用。此外,如果有nthreads = 1,TBB 实际上会创建 1 个额外的线程 - 加上主线程总共 2 个线程。
是的,在某些情况下,您确实希望完全关闭线程,但仍保持 TBB 代码处于活动状态。我当前的解决方案是对 tbb 进行草率的包装:
namespace hddm {
bool enableTBB = true;
class task_group {
unique_ptr<tbb::task_group> tbb;
public :
task_group() {
if (enableTBB)
tbb.reset(new tbb::task_group());
}
template<typename F>
void run(const F& f) { …Run Code Online (Sandbox Code Playgroud) 下面是Triton 编译器生成的明显合法的 PTX 汇编代码。我对加载和存储指令感到困惑{ %r1 }和使用。{ %r2 }根据 PTX ISA 文档,它看起来像一个初始值设定项列表。但这没有意义。不仅因为初始化规范没有提到寄存器的使用。甚至不是因为加载/存储语义中的初始化器是无用的(没有什么可以初始化)。最重要的是,我对加载/存储中的使用将{}参数的含义从标量更改为指针立即数这一事实感到困惑。
也许,一个无聊的开发者只是想让每个人的组装体验更加混乱。有谁有更好的解释吗?
.version 7.5
.target sm_35
.address_size 64
// .globl E__01
.visible .entry E__01(
.param .u64 E__01_param_0,
.param .u64 E__01_param_1
)
.maxntid 128, 1, 1
{
.reg .pred %p<3>;
.reg .b32 %r<4>;
.reg .b64 %rd<3>;
.loc 1 6 0
$L__func_begin0:
.loc 1 6 0
ld.param.u64 %rd2, [E__01_param_0];
ld.param.u64 %rd1, [E__01_param_1];
mov.pred %p1, -1;
$L__tmp0:
.loc 1 7 19
mov.u32 %r1, 0x0; …Run Code Online (Sandbox Code Playgroud)