[英]How is performance dependent on the underlying data values
我有以下C ++代碼片段(C ++部分是此處省略的分析器類),使用VS2010(64位Intel機器)編譯。 代碼簡單地將浮點數組( arr2
)與標量相乘,並將結果放入另一個數組( arr1
):
int M = 150, N = 150;
int niter = 20000; // do many iterations to have a significant run-time
float *arr1 = (float *)calloc (M*N, sizeof(float));
float *arr2 = (float *)calloc (M*N, sizeof(float));
// Read data from file into arr2
float scale = float(6.6e-14);
// START_PROFILING
for (int iter = 0; iter < niter; ++iter) {
for (int n = 0; n < M*N; ++n) {
arr1[n] += scale * arr2[n];
}
}
// END_PROFILING
free(arr1);
free(arr2);
為簡單起見,這里省略了從文件讀取部分和分析(即運行時間測量)。
當arr2
初始化為[0 1]范圍內的隨機數時,與arr2
初始化為稀疏數組的情況相比,代碼運行速度快約10倍,其中約2/3的值為零。 我使用了編譯器選項/fp
和/O
,它稍微改變了運行時間,但是大約保持1:10的比例。
編輯
完整的代碼在這里: https : test.cpp
用於編譯的命令行在test.cpp
中的注釋中。
數據文件在這里:
可能這是因為你的“快速”數據只包含正常的浮點數,但你的“慢”數據包含大量的非規范化數字。
至於你的第二個問題,你可以嘗試用這個提高速度(並將所有非規范化數字視為精確零):
#include <xmmintrin.h>
_mm_setcsr(_mm_getcsr() | 0x8040);
我可以想到兩個原因。
首先,分支預測器可能做出錯誤的決定。 這是由數據更改引起的性能差距的一個潛在原因,無需更改代碼。 但是,在這種情況下,似乎不太可能。
第二個可能的原因是你的“大多數零”數據並不真正由零組成,而是幾乎為零,或者你將arr1
保持在幾乎為零的范圍內。 請參閱此Wikipedia鏈接 。
沒有什么奇怪的,來自I.bin的數據需要更長的時間來處理:你有很多數字,如'1.401e-045 #DEN'或'2.214e-043 #DEN',其中#DEN表示該數字無法規范化為標准浮點精度。 鑒於你要將它乘以6.6e-14,你肯定會有下溢異常,這會大大減慢計算速度。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.