在c ++中复制和操作大型,密集的2D数组的最快方法是什么

时间:2012-12-23 18:28:02

标签: c++ arrays performance parallel-processing opencl

我正在尝试优化我的代码,利用多核处理器来复制任何操作大型密集阵列。

复制:我有一个大密集阵列(大约6000x100000),我需要从中拉出15x100000子阵列,在管道上进行多次计算。该管道由许多线性代数函数组成,这些函数由blas处理,这是多核的。与线性代数相比,提取数据的时间是否真的重要是一个悬而未决的问题,但我想谨慎一点,确保数据复制得到优化。

用于操作:我有许多不同的函数可以通过元素或行来操作数组。如果每个都是多核的话,那将是最好的。

我的问题是:最好是使用正确的框架(OpenML,OpenCL)并让编译器发生所有魔术,还是有更好的功能/库可以更快地完成这个?

1 个答案:

答案 0 :(得分:7)

你的出发点应该是好的memcpy。很长一段时间以来一直困扰着#34;复制表演的人的一些提示。

  1. 阅读What Every Programmer Should Know About Memory
  2. 评估您的系统memcpy效果,例如memcpy_bench功能here
  3. memcpy多个核心上运行时multi_memcpy_bench的可扩展性进行基准测试,例如rep movsd here。 (除非您使用的是多插槽NUMA硬件,否则我认为您不会看到多线程复制带来多大好处。)
  4. 深入了解系统对memcpy的实现并理解它们。你发现大部分时间花在单独movntps上的日子早已不复存在;上次我看了gcc和英特尔编译器的CRT时,他们都改变了策略,具体取决于副本相对于CPU缓存大小的大小。
  5. 在英特尔上,了解非缓存污染商店说明(例如{{1}})的优势,因为与传统方法相比,这些指令可以达到significant throughput improvements(您将在4中看到这些用法) 。)
  6. 可以访问并了解如何使用抽样分析器来确定您的应用程序的数量。复制操作花费的时间。还有更高级的工具可以查看CPU性能计数器,并告诉您各种缓存正在做什么等各种事情。
  7. (高级主题)注意TLB和when huge pages can help
  8. 但我的期望是,与任何linalg举重相比,你的副本将是相当小的开销。知道这些数字是多么好。我不希望OpenCL或任何 for CPU 在这里神奇地提供任何改进(除非你的系统的memcpy执行得不好);恕我直言,更详细地深入研究这些内容,深入了解在指令,寄存器,缓存行和页面层面实际发生的事情的基础知识,而不是远离它通过在顶层层叠另一层抽象。

    当然,如果您正在考虑从当前使用的GPU加速线性代数版本的多核BLAS库中移植代码,这将成为一个完全不同(并且更加复杂)的问题(请参阅JayC& #39;以下评论)。如果你想要实质性的性能提升,你当然应该考虑它。