英特尔至强融核上的动态内存变慢
Posted
技术标签:
【中文标题】英特尔至强融核上的动态内存变慢【英文标题】:Dynamic memory slow down on Intel Xeon Phi 【发布时间】:2014-10-23 15:38:36 【问题描述】:我正在创建一个简单的矩阵乘法程序,在英特尔至强融核架构上运行。程序如下所示(参数为 A、B、C),时序不包括初始化:
//start timing
for(int i = 0; i < size; i++)
for(int k = 0; k < size; k++)
register TYPE aik = A[i][k];
for(int j = 0; j < size; j++)
C[i][j] += aik * B[k][j];
//end timing
我正在使用限制、对齐数据等。但是,如果使用动态内存 (posix_memalign) 分配矩阵,则计算会严重减慢,即对于 TYPE=float 和 512x512 矩阵,在动态情况下大约需要 0.55 秒,而在其他情况下大约需要 0.25 秒。在不同的架构(英特尔至强 E5)上,也会出现减速,但几乎不明显(大约 0.002 秒)。
感谢任何帮助!
【问题讨论】:
所有这些数组的大小是多少?也许它不适合所有缓存或跨越缓存行或其他什么?您是否尝试过切换两个外部循环? 另外,register
storage specifier 已被弃用。
如果你想进行快速矩阵乘法,你真的想得到 BLAS 库而不是自己编写代码(提示:朴素算法并不是最快的方法!)。我确信英特尔有一款针对 Xeon Phi 进行了高度调整。
@JoachimPileborg,每行 2048 个字节(每个浮点数 4 个字节,512 个元素)。谢谢,我不知道register
已被弃用。一般来说,它不适合缓存(即 32K l1、512k L2),但是看起来很奇怪的是两种不同矩阵存储之间的巨大行为差异。 @IraBaxter,谢谢,但我需要自己按顺序编写代码,因为它只是评估待实现并行解决方案性能的“草图”。
您的“待实现”并行解决方案应与现有的最佳实现进行比较。将它们与相对于现代架构组织得很差的算法进行比较可能表明您可以比简单的解决方案更快地编写代码,但您不会因此而获得布朗尼积分。
【参考方案1】:
如果您使矩阵大小不同,时间差异会发生什么? (例如 513x513)
我问的原因是我认为您可能会看到这种效果,因为当您在 k 上的循环中循环 B 时,超出了缓存方式的关联性并从 L2 中逐出 C[i][] 的元素。如果 B 和 C 对齐并且大小是 2 的幂,您可能会遇到导致此问题的缓存超级对齐。
如果 B 和 C 在堆栈上或未对齐,您不会看到这种效果,因为更少的地址是 2 的幂对齐。
【讨论】:
【参考方案2】:在“非动态”情况下,数组是否只是全局变量?如果是这样,它们最终会出现在 BSS 中,当加载 ELF 时,操作系统会默认将它们初始化为零 - 这就是 BSS 的工作方式。如果您动态分配它们,而与您使用的方法无关(即 malloc、new、posix_memalign、exception is mmap(MAP_POPULATE)),当您触摸内存时,您将在操作系统中导致错误。故障处理总是很昂贵的。它在协处理器上相对更昂贵,因为从单线程性能的角度来看,您是在一个很小的内核上运行的。
【讨论】:
以上是关于英特尔至强融核上的动态内存变慢的主要内容,如果未能解决你的问题,请参考以下文章