我将改造我的自定义图形引擎,以便它利用多核CPU.更确切地说,我正在寻找一个并行化循环的库.
在我看来,OpenMP和英特尔的Thread Building Blocks都非常适合这项工作.此外,Visual Studio的C++编译器和大多数其他流行的编译器都支持它们.这两个库看起来都非常简单易用.
那么,我应该选择哪一个?有没有人尝试过两个库,可以给我一些利弊和使用任何一个库的优点?另外,你最终选择了什么?
谢谢,
阿德里安
我的新应用程序我可以灵活地决定使用库进行多线程.到目前为止我一直在使用pthread.现在想探索跨平台库.我对TBB和Boost不感兴趣.我不明白TBB比Boost有什么好处.我试图找出TBB相对于Boost的优势:TBB摘录wiki"相反,该库通过允许将操作视为"任务"来抽象对多个处理器的访问,这些任务由库的运行分配给各个核心 - 时间引擎,并自动有效地使用缓存.TBB程序根据算法创建,同步和销毁相关任务的图形,"
但是线程库甚至需要担心线程分配到核心.这不是操作系统的工作吗?那么使用TBB而不是Boost的真正优势是什么呢?
我打算开始为一个跨平台项目"玩"基于任务的并行性.我想使用英特尔线程构建模块.我从Windows和Visual Studio开始.
因为我只是想要原型,我正在考虑只在Windows上"玩",然后有足够的知识在所有兼容平台上使用该库.
我了解到,自VS2010以来,Microsoft提供了一个类似的库,并行处理库,它具有(几乎)与英特尔TBB相同的接口.
一些消息来源建议,包括TBB的团队博客,他们一起构建它,并且它是相同的库.
然而,它并不是真正明确的,因为它经常表明两个库之间存在细微差别.
那么,如果有的话,这些差异是什么?我应该直接与去年稳定该局启动或者是低风险的原型与微软PPL只是玩,跨平台的"真实"的项目上使用该局?
什么是tbb::scalable_allocator英特尔线程构建模块实际上是引擎盖下呢?
它肯定是有效的.我刚用它来采取25%的折扣的应用程式的执行时间(并看到在CPU利用率从〜200%4核系统上增加至350%),通过改变单个std::vector<T>给std::vector<T,tbb::scalable_allocator<T> >.另一方面,在另一个应用程序中,我看到它将已经很大的内存消耗加倍并将内容发送到交换城市.
英特尔自己的文档并没有给出太多帮助(例如本常见问题解答末尾的简短部分 ).在我自己去挖掘代码之前,谁能告诉我它使用了什么技巧?
更新:刚刚第一次使用TBB 3.0,并且从Scalable_allocator看到了我最好的加速.改变单一vector<int>的vector<int,scalable_allocator<int> >(从测试的Debian莱尼,核2,与TBB 3.0)的从85S东西35S减少的运行时间.
英特尔的线程构建模块(TBB)开源库看起来非常有趣.即使有一篇关于这个主题的O'Reilly书,我也听不到有很多人在使用它.我有兴趣将它用于Unix(Mac,Linux等)环境中的一些多级并行应用程序(MPI +线程).对于它的价值,我对高性能计算/数值方法的各种应用感兴趣.
有没有人有TBB的经验?它运作良好吗?它是否相当便携(包括GCC和其他编译器)?这个范例是否适用于您编写的程序?我应该研究其他图书馆吗?
我们目前正在使用TBB流程图,其中a)并行过滤器处理数组(与偏移并行)并将处理结果放入中间向量(在堆上分配;大多数向量将增长到8MB).然后将这些矢量传递给节点,然后节点根据它们的特性(在a中确定)对这些结果进行后处理.由于资源同步,每个特征只能有一个这样的节点.我们编写的原型在UMA架构上运行良好(在单CPU Ivy Bridge和Sandy Bridge架构上测试).但是,该应用程序无法在我们的NUMA架构(4 CPU Nehalem-EX)上扩展.我们将问题归结为内存分配并创建了一个最小的示例,其中我们有一个并行管道,它只是从堆中分配内存(通过8MB块的malloc,然后memset 8MB区域;类似于初始原型所做的)达到一定的记忆力.我们的发现是:
在UMA架构上,应用程序与管道使用的线程数呈线性关系(通过task_scheduler_init设置)
在NUMA架构上,当我们将应用程序固定到一个插槽(使用numactl)时,我们看到相同的线性放大
在我们使用多个套接字的NUMA架构中,我们的应用程序运行的时间随着套接字的数量而增加(负线性比例 - "向上")
对我们来说,这就像堆争用一样.我们到目前为止尝试的是将英特尔的TBB可扩展分配器替换为glibc分配器.但是,单个套接字上的初始性能比使用glibc更差,在多个套接字上性能不会变差但也没有变得更好.我们使用tcmalloc,hoard分配器和TBB的缓存对齐分配器获得了相同的效果.
问题是,是否有人遇到类似的问题.堆栈分配对我们来说不是一个选项,因为我们希望在管道运行后保持堆分配的向量.一个堆如何在多个线程的NUMA体系结构上有效地分配MB大小的内存区域?我们真的希望保持动态分配方法,而不是预先分配内存并在应用程序中管理内存.
我用numactl为各种执行附加了perf stats.Interleaving/localalloc无任何影响(QPI总线不是瓶颈;我们通过PCM验证,QPI链路负载为1%).我还添加了一个描绘glibc,tbbmalloc和tcmalloc结果的图表.
perf stat bin/prototype 598.867
'bin/prototype'的性能计数器统计信息:
12965,118733 task-clock # 7,779 CPUs utilized
10.973 context-switches # 0,846 K/sec
1.045 CPU-migrations # 0,081 K/sec
284.210 page-faults # 0,022 M/sec
17.266.521.878 cycles # 1,332 GHz [82,84%]
15.286.104.871 stalled-cycles-frontend # 88,53% frontend cycles idle [82,84%]
10.719.958.132 stalled-cycles-backend # 62,09% backend cycles idle [67,65%]
3.744.397.009 instructions # 0,22 insns per cycle
# 4,08 stalled cycles per insn [84,40%]
745.386.453 branches …Run Code Online (Sandbox Code Playgroud) 我是openCV的新手,我尝试过一些教程.一切正常,直到我包括:opencv2/imgproc/imgproc.hpp并使用filter2D函数.我启动程序时遇到以下错误:
"程序无法启动,因为您的计算机缺少tbb_debug.dll."
在互联网上,我发现这个错误与32位和64位版本的dll有关.
我正在使用64位版本的Windows并在VS2010中创建了一个32位控制台应用程序,该应用程序使用32位版本的openCV dll.当我启动程序"dependency walker"时,我可以看到我的程序使用所有系统dll的64位版本(在C:\ windows\system32 ....中).只有opencv的dll是32位.
depenency walker的屏幕截图:
谢谢
如何将intel的TBB库静态链接到我的应用程序?我知道所有警告,例如调度程序的不公平负载分配,但我不需要调度程序,只需要容器,所以没关系.
无论如何我知道这可以做到,虽然它没有记录,但我现在似乎无法找到方法(尽管我在某处之前已经看过它).
那么有人知道或有任何线索吗?
谢谢