c++ - 在 C++ 中复制和操作大型密集二维数组的最快方法是什么

标签 c++ arrays performance parallel-processing opencl

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

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

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

我的问题是:是否最好使用正确的框架(OpenML、OpenCL)并让编译器产生所有的魔力,还是有更好的函数/库可以更快地做到这一点?

最佳答案

您的起点应该是很好的旧memcpy。长期痴迷于“复制性能”的人的一些小窍门。

  1. 阅读What Every Programmer Should Know About Memory .
  2. 对您的系统 memcpy 性能进行基准测试,例如 memcpy_bench 函数 here .
  3. memcpy 在多个内核上运行时的可扩展性进行基准测试,例如 multi_memcpy_bench here . (除非您使用的是某些多插槽 NUMA 硬件,否则我认为您不会看到多线程复制有太多好处)。
  4. 深入研究您系统的 memcpy 实现并理解它们。您会发现大部分时间花在孤独的rep movsd 上的日子早已一去不复返了;上次我查看 gcc 和 Intel 编译器的 CRT 时,它们都根据相对于 CPU 缓存大小的拷贝大小改变了策略。
  5. 在 Intel 上,了解非缓存污染存储指令(例如 movntps)的优势,因为它们可以实现 significant throughput improvements与传统方法对比(您将在第 4 步中看到这些方法。)
  6. 可以访问并知道如何使用采样分析器来确定您的应用有多少时间花在了复制操作上。还有更高级的工具可以查看 CPU 性能计数器并告诉您有关各种缓存正在做什么等的各种信息。
  7. (高级主题)注意 TLB 和 when huge pages can help .

但我的期望是,与任何 linalg 繁重的工作相比,您的拷贝的开销将非常小。不过,了解这些数字是件好事。我不希望 OpenCL 或任何 for CPU 能够神奇地提供任何改进(除非您系统的 memcpy 实现不当);恕我直言,最好更详细地研究这些东西,深入了解指令、寄存器、缓存行和页面级别实际发生的事情的基础知识,而不是通过在顶部分层另一个抽象级别来摆脱它.

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

关于c++ - 在 C++ 中复制和操作大型密集二维数组的最快方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14013526/

相关文章:

php - PHP/MySQL 查询速度慢。重新考虑请求的帮助。 (160k 和 300 行表长度)

c++ - 当您在范围内创建新对象并退出时会发生什么

c++ - 'delete' 在 clang 中完美编译时在 g++ 中抛出错误

c++ - UML 中的首选组合或聚合是什么?

c++ - 复制构造函数调用

c - C 中的 bool 数组和按位运算

javascript - 返回数组中没有重复项的唯一元素

javascript - 如何将对象数组中的数组中的值与对象的属性进行比较?

performance - 在 matlab 中运行编译的 mex 代码时,mingw 是否比 cygwin 慢?

php - 禁用模块会提高 PHP 性能吗?