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

Dev*_*erp 10 c++ arrays parallel-processing performance opencl

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

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

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

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

tim*_*day 7

你的出发点应该是好的memcpy.长期以来一直被"复制表现"所困扰的人的一些提示.

  1. 阅读每个程序员应该了解的内存.
  2. 在此对功能进行基准测试,memcpy例如memcpy_bench功能.
  3. 基准测试memcpy在多核上运行时的可扩展性,例如multi_memcpy_bench 此处.(除非您使用的是多插槽NUMA硬件,否则我认为您不会看到多线程复制带来太多好处).
  4. 深入了解系统的memcpy实现并理解它们.你在大部分时间里独自度过的日子rep movsd早已不复存在; 上次我看了gcc和英特尔编译器的CRT时,他们都改变了策略,具体取决于副本相对于CPU缓存大小的大小.
  5. 在英特尔,了解非缓存污染存储指令(例如movntps)的优势,因为与传统方法相比,这些指令可以实现显着的吞吐量改进(您将在4中看到这些).
  6. 可以访问并了解如何使用抽样分析器来确定您的应用程序在复制操作中花费了多少时间.还有更高级的工具可以查看CPU性能计数器,并告诉您各种缓存正在做什么等各种事情.
  7. (高级主题)注意TLB以及大页面何时可以提供帮助.

但我的期望是,与任何linalg举重相比,你的副本将是相当小的开销.尽管知道数字是多少,但这很好.我不希望OpenCL或其他任何CPU在这里神奇地提供任何改进(除非你的系统的memcpy执行得不好); 恕我直言,最好更详细地深入研究这些内容,深入了解在指令,寄存器,缓存行和页面层面实际发生的事情,而不是通过在顶层层叠另一层抽象来远离它.

当然,如果您正在考虑将您目前使用的多核BLAS库中的代码移植到GPU加速线性代数版本,这将成为一个完全不同(并且复杂得多)的问题(请参阅下面的JayC评论).如果你想获得可观的性能提升,你当然应该考虑它.