首先, c語言本身沒有float在計算時要統統轉為double的規定. 那麼, 就要考慮一下實際情況了,一般來說, x86的CPU中有兩個單元可以被用來計算浮點數, 一個是遠古時期傳下來的FPU, 另一個是一脈傳承的SSE/AVX指令集. (當然我們也可以吃飽了撐的用其他整數指令集去計算浮點數, 但這沒有任何意義. )
其中, FPU指令集內部使用80位精度計算浮點數, 無論你讀寫是多少位, 內部永遠是80位計算. 所以一些腐朽發臭不負責任的過時教材中所謂"在計算時會轉換成double"這句話, 是從只擁有FPU的遠古時期傳下來的, 而且還是錯的. 然而以今天的角度來看, FPU架構又老, 速度又超級超級慢, 介面還超級超級隱晦, 而且近20年沒有任何升級. 根本不是人用的. 也不是現代程式設計師應該關注的. 除非為了相容極老的電腦, 在編譯浮點操作時編譯器自己輕易是不會生成FPU的彙編命令的. 一般開發時也頂多考慮相容到SSE一代就可以了. 畢竟SSE一代出現在1999年.
那麼再說回SSE/AVX, 它和FPU就完全不一樣了. 是float就按float計算, 是double就按double計算. 僅僅從指令本身來說, 由於SSE指令集是SIMD流水線指令, 它可以一次處理4個float或者2個double. AVX指令則是一次8個float或者4個double, AVX512則是16個和8個. 從這個角度來看, 彷彿在以流水線方式處理float時, 它的速度是double的2倍. 實際使用時由於各種原因, 並不會出現真的快2倍的情況. 而且實際情況中也不是每次都能用得上SIMD指令一次計算多個數. 但粗略地說在使用SSE的情況下float比double算的快一些是沒太大問題的.
最後, 和一些初學者的直覺不同, "計算"本身並不是影響速度的最大原因. 假設需要的資料已經在暫存器中了, 那麼由於現代CPU的微觀並行化, 跑一條float指令和跑兩條double的SSE指令幾乎沒有太大速度區別. 真正的問題在於記憶體吞吐量. float資料的讀寫顯然的比double資料的讀寫省去了一半的資料量. 在CPU速度和記憶體速度不成比例的今天, 這個差距在資料量大時非常明顯.(我說的記憶體/CPU交換資料也包括各級快取,快取行對齊等等等等問題導致的速度損失)
綜上, 大致就是這樣, 供題主參考.
首先, c語言本身沒有float在計算時要統統轉為double的規定. 那麼, 就要考慮一下實際情況了,一般來說, x86的CPU中有兩個單元可以被用來計算浮點數, 一個是遠古時期傳下來的FPU, 另一個是一脈傳承的SSE/AVX指令集. (當然我們也可以吃飽了撐的用其他整數指令集去計算浮點數, 但這沒有任何意義. )
其中, FPU指令集內部使用80位精度計算浮點數, 無論你讀寫是多少位, 內部永遠是80位計算. 所以一些腐朽發臭不負責任的過時教材中所謂"在計算時會轉換成double"這句話, 是從只擁有FPU的遠古時期傳下來的, 而且還是錯的. 然而以今天的角度來看, FPU架構又老, 速度又超級超級慢, 介面還超級超級隱晦, 而且近20年沒有任何升級. 根本不是人用的. 也不是現代程式設計師應該關注的. 除非為了相容極老的電腦, 在編譯浮點操作時編譯器自己輕易是不會生成FPU的彙編命令的. 一般開發時也頂多考慮相容到SSE一代就可以了. 畢竟SSE一代出現在1999年.
那麼再說回SSE/AVX, 它和FPU就完全不一樣了. 是float就按float計算, 是double就按double計算. 僅僅從指令本身來說, 由於SSE指令集是SIMD流水線指令, 它可以一次處理4個float或者2個double. AVX指令則是一次8個float或者4個double, AVX512則是16個和8個. 從這個角度來看, 彷彿在以流水線方式處理float時, 它的速度是double的2倍. 實際使用時由於各種原因, 並不會出現真的快2倍的情況. 而且實際情況中也不是每次都能用得上SIMD指令一次計算多個數. 但粗略地說在使用SSE的情況下float比double算的快一些是沒太大問題的.
最後, 和一些初學者的直覺不同, "計算"本身並不是影響速度的最大原因. 假設需要的資料已經在暫存器中了, 那麼由於現代CPU的微觀並行化, 跑一條float指令和跑兩條double的SSE指令幾乎沒有太大速度區別. 真正的問題在於記憶體吞吐量. float資料的讀寫顯然的比double資料的讀寫省去了一半的資料量. 在CPU速度和記憶體速度不成比例的今天, 這個差距在資料量大時非常明顯.(我說的記憶體/CPU交換資料也包括各級快取,快取行對齊等等等等問題導致的速度損失)
綜上, 大致就是這樣, 供題主參考.