注意:这不是这个问题的重复。
给定一个与 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) 当我在代码中使用 oneDPL 时,我面临以下问题:
/usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/pstl/parallel_backend_tbb.h:70:10: error: no member named 'task' in namespace 'tbb'
Run Code Online (Sandbox Code Playgroud)
为什么会发生这种情况以及如何解决它?
我已经tbb下载并放置在我的存储库目录中:
> tree deps/tbb/ -d \ndeps/tbb/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 cmake\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 templates\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 serial\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tbb\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tbb\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 compat\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 internal\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 machine\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib\n \xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ia32\n \xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 gcc4.8\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 intel64\n \xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 gcc4.8\nRun Code Online (Sandbox Code Playgroud)\n在我的CMakeLists.txt我已经尝试过这个:
include_directories("deps/tbb/include")\n\n\nfind_library(TBB_LIB\n NAMES\n tbbbind_debug\n tbbbind\n tbb_debug\n tbbmalloc_debug\n tbbmalloc_proxy_debug\n tbbmalloc_proxy\n tbbmalloc\n tbb_preview_debug\n tbb_preview\n tbb\n HINTS "${CMAKE_PREFIX_PATH}/deps/tbb/lib/intel64/gcc4.8"\n)\n\nadd_executable(${PROJECT_NAME}\nsrc/main.cpp\n)\n\ntarget_link_libraries(${PROJECT_NAME} PUBLIC ${TBB_LIB})\nRun Code Online (Sandbox Code Playgroud)\n但是使用cmake, 链接器构建会引发此错误:
\n\n/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:找不到-lTBB_LIB-NOTFOUND
\ncollect2:错误:ld 返回 1 退出状态
\n
我无法弄清楚缺少什么。谢谢。
\n有些人可以推荐在C++中进行并行化的方法,当要执行的数据非常庞大时.我一直在阅读有关openMP和英特尔TBB在C++中进行并行化的内容,但尚未对它们进行过实验.哪些对并行数据处理更好?还有其他图书馆/方法吗?
我想尝试TBB的scalable_allocator,但在我不得不替换我的一些代码时感到困惑.这是分配器的分配方式:
SomeClass* s = scalable_allocator<SomeClass>().allocate( sizeof(SomeClass) );
Run Code Online (Sandbox Code Playgroud)
编辑:上面显示的不是如何使用scalable_allocator完成分配.正如ymett正确提到的,分配是这样完成的:
int numberOfObjectsToAllocateFor = 1;
SomeClass* s = scalable_allocator<SomeClass>().allocate( numberOfObjectsToAllocateFor );
scalable_allocator<SomeClass>().construct( s, SomeClass());
scalable_allocator<SomeClass>().destroy(s);
scalable_allocator<SomeClass>().deallocate(s, numberOfObjectsToAllocateFor);
Run Code Online (Sandbox Code Playgroud)
这很像使用malloc:
SomeClass* s = (SomeClass*) malloc (sizeof(SomeClass));
Run Code Online (Sandbox Code Playgroud)
这是我想要替换的代码:
SomeClass* SomeClass::Clone() const
{
return new SomeClass(*this);
}//Clone
Run Code Online (Sandbox Code Playgroud)
所以尝试了一个程序:
#include<iostream>
#include<cstdlib>
using namespace std;
class S
{
public:
int i;
S() {cout<<"constructed"<<endl;}
~S() {cout<<"destructed"<<endl;}
S(const S& s):i(s.i) {}
};
int main()
{
S* s = (S*) malloc(sizeof(S));
s = (S*) S();//this is obviously wrong
free(s);
} …Run Code Online (Sandbox Code Playgroud) 我刚开始使用ffmpeg-mt已合并到的最新版本的ffmpeg.
但是,由于我的应用程序使用TBB(英特尔线程构建模块),因此新的线程创建和同步的ffmpeg-mt实现不太合适,因为它可能会阻止执行解码功能的TBB任务.它也会不必要地丢弃缓存.
我在pthread.c中四处寻找,它似乎实现了ffmpeg用来启用多线程的接口.
我的问题是,是否有可能创建一个实现相同功能但使用tbb任务而不是显式线程的tbb.c?
我对C没有经验,但我的猜测是不可能轻易地将tbb(也就是C++)编译成ffmpeg.所以也许以某种方式在运行时覆盖ffmpeg函数指针将是要走的路?
对于将TBB实现为ffmpeg threading api的任何建议或意见,我将不胜感激.
为什么英特尔线程构建模块(TBB)parallel_for有如此大的开销?根据第3.2.2 自动分块在Tutorial.pdf其周围半毫秒.这是教程中的一个重点:
注意:对于parallel_for,循环通常需要至少一百万个时钟周期才能提高其性能.例如,在2 GHz处理器上占用至少500微秒的环路可能会受益于parallel_for.
从我到目前为止所读到的内容,TBB在内部使用了线程池(工作线程池)模式,它通过最初只生成工作线程(这需要数百微秒)来防止这种不良开销.
那么花时间呢?使用互斥锁进行数据同步并不是那么慢吗?此外,TBB不使用无锁数据结构进行同步吗?
我想使用TBB获得线程池行为.但每当我阅读有关TBB的文档时,他们总是谈论并行,并行 - 等等.相比之下,我需要的是一个主线程,用于将任务分配给线程池,以便这些任务将"自己"执行 - 执行任务异步.这里的任务可以是GUI的事件处理.
TBB任务调度程序是否适合此类行为?我从任务调度程序得到的印象是,如果我有可以分解并相互并行执行的任务,那将是有益的.
我在MinGW32下(在Windows 7 64位上)构建TBB并成功地将一个简单的程序链接到它.不幸的是,我的同事无法成功链接.我们都运行相同版本的Windows,相同版本的MinGW(mingw-get-inst-20110802),并试图编译完全相同的代码.我们的PATH环境变量完全相同(.:/ usr/local/bin:/ mingw/bin:/ bin).然而,尽管所有事情都是平等的(据我所知),我可以成功构建和运行程序,我的同事尝试在链接步骤失败了.如果我给他他的tbb.dll,那么他可以成功链接他的程序.因此,我被引导相信他的tbb.dll的构建有问题.我们已经确认(使用文件)我们正在为所有目标文件和库生成32位二进制文件
$ file a.exe
a.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit
$ file ./tbb/tbb30_20110704oss/lib/tbb.dll
./tbb/tbb30_20110704oss/lib/tbb.dll: PE32 executable for MS Windows (DLL) (console) Intel 80386 32-bit
Run Code Online (Sandbox Code Playgroud)
我们用于构建TBB的命令行是:
mingw32-make compiler=gcc arch=ia32 runtime=mingw tbb
Run Code Online (Sandbox Code Playgroud)
我们正在编译的简单测试程序是:
#include <tbb/task_scheduler_init.h>
using namespace tbb;
int main() {
task_scheduler_init init;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我们用来构建简单测试程序的命令行
g++ test1.cpp -I ./tbb/tbb30_20110704oss/include -L ./tbb/tbb30_20110704oss/lib -ltbb
Run Code Online (Sandbox Code Playgroud)
就我而言,它可以完美地构建和链接.在他的情况下,他收到错误消息:
test1.o: In function `tbb::task_scheduler_init::task_scheduler_init(int, unsigned int)':
test1.cpp:(.text._ZN3tbb19task_scheduler_initC1Eij[tbb::task_scheduler_init::task_scheduler_init(int, unsigned int)]+0x33): undefined reference to `tbb::task_scheduler_init::initialize(int, unsigned int)'
test1.o: In function …Run Code Online (Sandbox Code Playgroud) 我正在使用c ++为我的计算动力学研究开发一些代码.我的代码解决了稀疏和密集的矩阵,生成网格,并在最微不足道的意义上做类似的操作.我需要并行化我的代码以减少计算时间并为此目的使用OpenMP.
但仔细观察一下商用代码,比如ANSYS CFX,我发现该软件中使用的并行化方案是MPICH2,它是MPI的一种实现方式.
所以你有很多并行化工具/ API:
我使用了其中一些工具,并使用每个工具在本地计算机上获得100%的CPU使用率.
在选择合适的并行化工具时,我不知道应该注意什么标准.什么样的应用需要哪种工具?上述任何一项可用于研究目的吗?其中哪些主要用于商业软件?