我在群集上运行英特尔TBB。但是,我不知道如何检查活动和运行的线程数。有没有办法检查这个?
假设我有16个内核,所以我想知道我的TBB代码中是否正在使用所有16个内核。这样可以确保我的系统没有问题。
答案 0 :(得分:4)
我想知道我的TBB代码中是否正在使用所有16个内核。
假设在TBB中请求或期望多个线程并不总是导致创建此线程数,或者然后处理用户代码。 TBB遵循可选的并行性范例,该范例不保证特定数量的线程同时工作。而且,即使TBB创建了足够的线程,也并不意味着所有线程都能够加入给定的用户代码; task_scheduler_init
和task_arena
仅指定工作线程数的限制。
您可以使用task_scheduler_observer
来监控创建的工作线程数以及有多少人真正加入了您关注的任务领域。
This blog提供了如何计算创建的TBB工作线程的简单代码:
class concurrency_tracker: public tbb::task_scheduler_observer {
tbb::atomic<int> num_threads;
public:
concurrency_tracker() : num_threads() { observe(true); }
/*override*/ void on_scheduler_entry( bool ) { ++num_threads; }
/*override*/ void on_scheduler_exit( bool ) { --num_threads; }
int get_concurrency() { return num_threads; }
};
但它与可以显示进程中活动线程数的外部工具没有太大区别。为了检查加入您的计算区域(竞技场)的线程数,我们可以使用预览功能TBB_PREVIEW_LOCAL_OBSERVER
:
#define TBB_PREVIEW_LOCAL_OBSERVER 1
#include <tbb/task_scheduler_observer.h>
//...
class concurrency_tracker: public tbb::task_scheduler_observer {
tbb::atomic<int> num_threads;
tbb::atomic<int> max_threads;
public:
concurrency_tracker()
: tbb::task_scheduler_observer(true) // request implicit arena observation
, num_threads(), max_thread()
{
observe(true);
}
/*override*/ void on_scheduler_entry( bool )
{
int current_num = ++num_threads; // increment instant concurrency counter
int current_max = max_threads;
while( current_max < current_num ) // update max concurrency value
current_max = max_threads.compare_and_swap(current_num, current_max);
}
/*override*/ void on_scheduler_exit( bool ) { --num_threads; }
int get_instant_concurrency() { return num_threads; }
int get_peak_concurrency() { return max_threads; }
};
最后,可以使用TLS(例如tbb::enumerable_thread_specific
)直接从并行算法内部完成相同的技巧,因为它在TBB单元测试源的src/test/harness_concurrency_tracker.h
文件中实现。它可以并行跟踪有多少特定任务实例正在运行。