3

我有:

final int ROWS = 100000;
final int COLS = 2000;
long[][] m = new long[COLS][ROWS];

接着:

public void xor(int row1, int row2) {
    for (int col=0; col<COLS; col++) {
        m[col][row1] ^= m[col][row2];
    }
}

上面的函数是简化的,它在运行中花费了大部分时间。我想知道是否应该花时间重构我的整个程序以读取“m = new long[ROWS][COLS]”(而不是相反)以获得更好的 RAM 访问。或者我不会赢得很多时间?

我知道我可以将它与 GPU 并行化,但那是为了以后的阶段。

4

1 回答 1

1

在我看来,交换 ROWS 和 COLS 肯定会有所帮助。

这个数组的布局(大致)是这样的:[0][0], [0][1], [0][2],... [1][0], [1][1], ... 等等。在您的代码中,每一列都是一块连续的内存,而一行不是。

由于每列是 800000 字节,并且在您的xor方法中您访问所有这些,您正在强制更多的缓存未命中。

转置后,每一行都成为一块连续的内存,并且由于您倾向于对行进行操作,因此应该使其更快。

如果您有long[][] m = new long[ROWS][COLS];and ,则在执行该方法for (int col=0; col<COLS; col++) m[row1][col] ^= m[row2][col];期间,您只需要两个 16000 字节长的行在缓存中。xor

但是由于我所说的主要基于理论,因此请尝试对这两种变体进行基准测试并检查哪个变体真正更快。

于 2013-09-17T16:06:04.890 回答