[英]Double vs Float vs _Float16 (Running Time)
我有一個 C 語言的簡單問題。 我正在使用 C 中的 _Float16 實現半精度軟件(我的 mac 基於 ARM),但運行時間並不比單精度或雙精度軟件快。 我用一個非常簡單的代碼測試了一半,單,雙,就像只是添加數字一樣。 一半的速度比單人或雙人的慢。 此外,single 類似於 double。
typedef double FP;
// double - double precision
// float - single precision
// _Float16 - half precision
int main(int argc, const char * argv[]) {
float time;
clock_t start1, end1;
start1 = clock();
int i;
FP temp = 0;
for(i = 0; i< 100; i++){
temp = temp + i;
}
end1 = clock();
time = (double)(end1 - start1)/CLOCKS_PER_SEC;
printf("[] %.16f\n", time);
return 0;
}
在我的預期中,半精度比單精度或雙精度要快得多。 如何檢查半精度更快,浮點數比雙精度更快?
請幫我。
這是關於浮點的一個非常令人驚訝的事實:
單精度 (
float
) 算術不一定比雙精度快。
怎么會這樣? 浮點運算很難,所以以兩倍的精度來做至少兩倍的難度,而且必須花費更長的時間,對吧?
嗯,不。 是的,以更高的精度進行計算需要更多的工作,但只要工作是由專用硬件(通過某種浮點單元或 FPU)完成的,一切都可能並行發生。 雙精度的難度可能會增加一倍,因此專用於它的晶體管數量可能會增加一倍,但不會再花更多的時間了。
事實上,如果您的系統具有同時支持單精度和雙精度浮點的 FPU,那么一個好的規則是:始終使用double
。 這條規則的原因是float
類型通常不夠准確。 所以如果你總是使用double
,你會經常避免數字不准確(如果你使用float
,那會殺了你),但它不會變慢。
現在,到目前為止,我所說的一切都假定您的 FPU確實支持您關心的硬件類型。 如果存在硬件不支持的浮點類型,如果必須在軟件中進行模擬,那么它顯然會更慢,通常會慢得多。 這種影響至少體現在三個方面:
float
在那里可能是有利的。)float
或double
慢得多也就不足為奇了。我已將代碼的相關部分提取到 C++ 中,以便可以輕松地為每種類型實例化它:
template<typename T>
T calc() {
T sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
在 Clang 中使用優化 ( -O3
) 編譯它並查看Godbolt上的程序集列表表明:
double
版本在內循環中的指令數量最少(4)float
版本的內循環有 5 條指令,看起來和double version
基本不相上下_Float16
版本在內循環中有 9 條指令,因此可能是最慢的。 額外的指令是在fcvt
和 float32 格式之間轉換的 fcvt。請注意,計數指令只是性能的粗略指南! 例如,有些指令需要多個周期才能執行,而流水線執行意味着可以並行執行多條指令。
Clang 的語言擴展文檔表明_Float16
在 ARMv8.2a 上受支持,而 M1 似乎是 v8.4,所以大概它也支持這一點。 不過,我不確定如何在 Godbolt 中啟用此功能,抱歉!
我會使用clock_gettime(CLOCK_MONOTONIC)
在Linux 下進行高精度(即納秒)計時。 OSX 似乎沒有提供此功能,但在 OSX 上似乎可以使用 Monotonic clock替代方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.