1

我正在创建一个简单的矩阵乘法程序,在 Intel Xeon Phi 架构上运行。程序看起来像这样(参数是 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 秒)。

任何帮助都将不胜感激!

4

2 回答 2

1

如果使矩阵大小不同,时间差异会发生什么?(例如 513x513)

我问的原因是我认为您可能会看到这种效果,因为当您在 k 上的循环中循环 B 时,超出了缓存方式的关联性并从 L2 中逐出 C[i][] 的元素。如果 B 和 C 对齐并且大小是 2 的幂,您可能会遇到导致此问题的缓存超级对齐。

如果 B 和 C 在堆栈上或未对齐,您不会看到这种效果,因为更少的地址是 2 的幂对齐。

于 2014-10-23T16:26:27.050 回答
0

在“非动态”情况下,数组只是全局变量吗?如果是这样,它们最终会出现在 BSS 中,当加载 ELF 时,操作系统会默认将它们初始化为零 - 这就是 BSS 的工作方式。如果您动态分配它们,而与您使用的方法无关(即 malloc、new、posix_memalign、异常是 mmap(MAP_POPULATE)),当您触摸内存时,您将导致操作系统出现故障。故障处理总是很昂贵的。它在协处理器上相对更昂贵,因为从单线程性能的角度来看,你是在一个很小的内核上运行的。

于 2014-10-24T18:52:17.233 回答