以下示例代碼生成大小N
的矩陣,並且調換它SAMPLES
的次數。 當N = 512
轉置運算的平均執行時間是2144 μs
(coliru link)。 第一眼看上去沒有什麼特別的,對不對?......這些矩陣換位時間爲什麼如此違反直覺?
嗯,這裏是
N = 513
→1451 μs
N = 519
→600 μs
N = 530
→486 μs
N = 540
結果→492 μs
(最後!理論開始工作:)。
那麼,爲什麼在實踐中這些簡單的計算,從理論上如此不同?這種行爲與CPU緩存一致性或緩存未命中有關嗎?如果是這樣,請解釋。
#include <algorithm>
#include <iostream>
#include <chrono>
constexpr int N = 512; // Why is 512 specifically slower (as of 2016)
constexpr int SAMPLES = 1000;
using us = std::chrono::microseconds;
int A[N][N];
void transpose()
{
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < i ; j++)
std::swap(A[i][j], A[j][i]);
}
int main()
{
// initialize matrix
for (int i = 0 ; i < N ; i++)
for (int j = 0 ; j < N ; j++)
A[i][j] = i+j;
auto t1 = std::chrono::system_clock::now();
for (int i = 0 ; i < SAMPLES ; i++)
transpose();
auto t2 = std::chrono::system_clock::now();
std::cout << "Average for size " << N << ": " << std::chrono::duration_cast<us>(t2 - t1).count()/SAMPLES << " (us)";
}
你運行過這段代碼多少次?根據您的系統可能做多少其他事情,運行時可能會因運行而異。這些是大約10或20次運行的平均時間,還是單次運行的時間? – JGroven
可能512是一個魔術般的大小,可以適應緩存可怕,所以你會得到很多緩存未命中。其他尺寸適合更好,所以你得到更少的失誤。 – NathanOliver
錯誤的方式@NathanOliver - 512比* 513慢* * –