2016-06-24 30 views
1

我已經在這裏找到了PRIMATEs密碼的一個分片實現:http://primates.ae/(我做了它的120位版本)。從QueryPerformanceCounter()計算週期/字節

我完全使用C語言編寫並使用了Intel Intrinsics,這樣我就可以使用AVX2指令集。

由於我做了一個切片的實現,我想優化它的速度,從而衡量性能,我計算每個字節的週期。爲此,我使用Windows提供的QueryPerformanceCounter()函數

現在是事情了。在我的計算中,我使用了每個字節1,91個週期,這看起來好像是好。我覺得我一定在做錯事(我不是那麼好的編碼員)。這就是我要做的事:

//Size of testdata 
int testDataSize = 4000; //bytes 

//Get CPU frequency (cycles per sec) 
LARGE_INTEGER start, finish; 
double cpu_frequency; 
QueryPerformanceFrequency(&start); 
cpu_frequency = (double)(start.QuadPart) 

QueryPerformanceCounter(&start); 
encrypt(data); 
decrypt(data); 
QueryPerformanceCounter(&finish); 

double cyclesUsed = (double)(finish.QuadPart - start.QuadPart); 
double bytesSecond = (cpu_frequency/cyclesUsed) * testDataSize; 
double bytesCycle = bytesSecond/cpu_frequency; 
double cycles_per_byte = 1/bytesCycle; 

在運行時,這兩個QueryPerformanceCounter的調用之間的花(即時間加密和解密)的週期爲開始之間的增量完成,大約是7674個週期。這是4000字節的時間。我自然會使用每個字節大約1.9個週期,但是這看起來確實很好......我是否正確實現了週期/字節計算,並且正確理解了QueryPerformanceCounter()的使用方法?或者我現在正在計算一些隨機數。

此外,如果有人知道:這是一個現實的價值,通常用現代密碼加密/解密數據?我知道這對該領域是主觀的,很難回答,但值得一試......無論是哪種情況,我是否已經正確實施它是我現在最想知道的,因爲我可以看到我的測試向量通過與這些結果。

我用英特爾TurboBoost關閉測試,只用1個CPU核心....我無法關閉超線程(謝謝你簡化的聯想BIOS),但我懷疑它會有所作爲,因爲我的代碼是單線程。

+1

您可能想使用rdtsc – Dani

+0

謝謝。我剛剛沒有這樣做就學到了一個辛苦學到的教訓,並且從現在開始將這樣做。 __rdtsc似乎很有用,會給它一個檢查! – oPolo

回答

3

您的代碼是正確的,但是您誤解了數據。 QueryPerformanceFrequency()不給你CPU的頻率,它給你的性能計數器頻率。這意味着你正在計算任意刻度,而不是週期。使用Windows性能計數器(CPU頻率通常是動態的)沒有簡單的方法來獲得週期數,但是您可以獲得相當不錯的執行時間。

+0

非常感謝您的回答,我確實認爲這裏有些東西沒有。很高興澄清。 QueryPerformanceFrequency在我的情況下返回2533192.00。如果我的CPU是2.533Ghz(Turbo boost關閉,所以它穩定在那個值),這是否意味着我的計算結果是1000倍? – oPolo

+1

@oPolo是的,可能。性能計數器只擅長測量時間,所以你應該計算吞吐量(MB/s)。我正在刪除「通常爲100MHz」的部分,似乎我對其他內容感到困惑。 – ElderBug

+0

實際的perf計數器硬件可以測量核心時鐘週期,而不是TSC週期。不要混淆一些Windows功能的命名。 IDK在Windows上如何做,但在Linux上可以運行'perf stat。/ a.out'並查看整個程序所花費的核心時鐘週期。 –