亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 操作系統 > 正文

你應該知道的浮點數基礎知識

2024-06-28 13:21:13
字體:
來源:轉載
供稿:網友
你應該知道的浮點數基礎知識

本文從一個有趣而又令人意外的實驗展開,介紹一些關于浮點數你應該知道的基礎知識

本博客已經遷移至:

http://cenalulu.github.io/

為了更好的體驗,請通過此鏈接閱讀:

http://cenalulu.github.io/linux/about-denormalized-float-number/

文章歡迎轉載,但轉載時請保留本段文字,并置于文章的頂部作者:盧鈞軼(cenalulu)本文原文地址:

一個有趣的實驗

本文從一個有趣而詭異的實驗開始。最早這個例子博主是從 Stackoverflow上的一個問題中看到的。為了提高可讀性,博主這里做了改寫,簡化成了以下兩段代碼:

#include <iostream>#include <string>using namespace std;int main() {    const float x=1.1;    const float z=1.123;    float y=x;    for(int j=0;j<90000000;j++)    {        y*=x;        y/=z;        y+=0.1f;        y-=0.1f;    }    return 0;}
#include <iostream>#include <string>using namespace std;int main() {    const float x=1.1;    const float z=1.123;    float y=x;    for(int j=0;j<90000000;j++)    {        y*=x;        y/=z;        y+=0;        y-=0;    }    return 0;}

上面兩段代碼的唯一差別就是第一段代碼中y+=0.1f,而第二段代碼中是y+=0。由于y會先加后減同樣一個數值,照理說這兩段代碼的作用和效率應該是完全一樣的,當然也是沒有任何邏輯意義的。假設現在我告訴你:其中一段代碼的效率要比另一段慢7倍。想必讀者會認為一定是y+=0.1f的那段慢,畢竟它和y+=0相比看上去要多一些運算。但是,實驗結果,卻出乎意料, y+=0的那段代碼比y+=0.1f足足慢了7倍。{: style="color: red" } 。世界觀被顛覆了有木有?博主是在自己的Macbook PRo上進行的測試,有興趣的讀者也可以在自己的筆記本上試試。(只要是支持SSE2指令集的CPU都會有相似的結果)。

shell> g++ code1.c -o test1shell> g++ code2.c -o test2shell> time ./test1real    0m1.490suser    0m1.483ssys     0m0.003sshell>?time ./test2real    0m9.895suser    0m9.871ssys     0m0.009s

當然 原文中的投票最高的回答解釋的非常好,但博主第一次看的時候是一頭霧水,因為大部分基礎知識已經還給大學老師了。所以,本著知其然還要知其所以然的態度,博主做了一個詳盡的分析和思路整理過程。也希望讀者能夠從0開始解釋這個詭異現象的原因。

復習浮點數的二進制轉換

現在讓我們復習大學計算機基礎課程。如果你熟練掌握了浮點數向二進制表達式轉換的方法,那么你可以跳過這節。我們先來看下浮點數二進制表達的三個組成部分。

float_exponent

三個主要成分是:

  • Sign(1bit):表示浮點數是正數還是負數。0表示正數,1表示負數
  • Exponent(8bits):指數部分。類似于科學技術法中的M*10^N中的N,只不過這里是以2為底數而不是10。需要注意的是,這部分中是以2^7-1127,也即01111111代表2^0,轉換時需要根據127作偏移調整。
  • Mantissa(23bits):基數部分。浮點數具體數值的實際表示。

下面我們來看個實際例子來解釋下轉換過程。Step 1 改寫整數部分以數值5.2為例。先不考慮指數部分,我們先單純的將十進制數改寫成二進制。整數部分很簡單,5.101.

Step 2 改寫小數部分小數部分我們相當于拆成是2^-1一直到2^-N的和。例如:0.2 = 0.125+0.0625+0.007825+0.003906252^-3+2^-4+2^-7+2^-8....,也即.00110011001100110011

Step 3 規格化現在我們已經有了這么一串二進制101.00110011001100110011。然后我們要將它規格化,也叫Normalize。其實原理很簡單就是保證小數點前只有一個bit。于是我們就得到了以下表示:1.0100110011001100110011 * 2^2。到此為止我們已經把改寫工作完成,接下來就是要把bit填充到三個組成部分中去了。

Step 4 填充指數部分(Exponent):之前說過需要以127作為偏移量調整。因此2的2次方,指數部分偏移成2+127即129,表示成10000001填入。整數部分(Mantissa):除了簡單的填入外,需要特別解釋的地方是1.010011中的整數部分1在填充時被舍去了。因為規格化后的數值整部部分總是為1。那大家可能有疑問了,省略整數部分后豈不是1.0100110.010011就混淆了么?其實并不會,如果你仔細看下后者:會發現他并不是一個規格化的二進制,可以改寫成1.0011 * 2^-2。所以省略小數點前的一個bit不會造成任何兩個浮點數的混淆。具體填充后的結果見下圖float_exponent

練習:如果想考驗自己是否充分理解這節內容的話,可以隨便寫一個浮點數嘗試轉換。通過 浮點二進制轉換工具可以驗證答案。

什么是Denormalized Number

了解完浮點數的表達以后,不難看出浮點數的精度和指數范圍有很大關系。最低不能低過2^-7-1最高不能高過2^8-1(其中剔除了指數部分全0喝全1的特殊情況)。那么當我們要表示一個例如:1.00001111*2^-7這樣的超小數值的時候就無法用規格化數值表示,只能用0來代替。那么,這樣做有什么問題呢?最容易理解的一種副作用就是:當多次做低精度浮點數舍棄的時候,就會出現除數為0的exception,導致異常。

于是乎就出現了Denormalized Number(后稱非規格化浮點)。他和規格浮點的區別在于,規格浮點約定小數點前一位默認是1。而非規格浮點約定小數點前一位可以為0,這樣小數精度就相當于多了最多2^22范圍。

但是,精度的提升是有代價的。由于CPU硬件只支持,或者默認對一個32bit的二進制使用規格化解碼。因此需要支持32bit非規格數值的轉碼和計算的話,需要額外的編碼標識,也就是需要額外的硬件或者軟件層面的支持。以下是wiki上的兩端摘抄,說明了非規格化計算的效率非常低。> 一般來說,由軟件對非規格化浮點數進行處理將帶來極大的性能損失,而由硬件處理的情況會稍好一些,但在多數現代處理器上這樣的操作仍是緩慢的。極端情況下,規格化浮點數操作可能比硬件支持的非規格化浮點數操作快100倍。

For example when using NVIDIA's CUDA platform, on gaming cards, calculations with double precision take 3 to 24 times longer to complete than calculations using single precision.

如果要解釋為什么有如此大的性能損耗,那就要需要涉及電路設計了,超出了博主的知識范圍。當然萬能的wiki也是有答案的,有興趣的讀者可以自行查閱。

回到實驗

總上面的分析中我們得出了以下結論:

  • 浮點數表示范圍有限,精度受限于指數和底數部分的長度,超過精度的小數部分將會被舍棄(underflow)
  • 為了表示更高精度的浮點數,出現了非規格化浮點數,但是他的計算成本非常高。

于是我們就可以發現通過幾十上百次的循環后,y中存放的數值無限接近于零。CPU將他表示為精度更高的非規格化浮點。而當y+0.1f時為了保留跟重要的底數部分,之后無限接近0(也即y之前存的數值)被舍棄,當y-0.1f后,y又退化為了規格化浮點數。并且之后的每次y*xy/z時,CPU都執行的是規劃化浮點運算。而當y+0,由于加上0值后的y仍然可以被表示為非規格化浮點,因此整個循環的四次運算中CPU都會使用非規格浮點計算,效率就大大降低了。

其他

當然,也有在程序內部也是有辦法控制非規范化浮點的使用的。在相關程序的上下文中加上fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);就可以迫使CPU放棄使用非規范化浮點計算,提高性能。我們用這種辦法修改上面實驗中的代碼后,y+=0的效率就和y+=0.1f就一樣了。甚至還比y+=0.1f更快了些,世界觀又端正了不是么:) 修改后的代碼如下

#include <iostream>#include <string>#include <fenv.h>using namespace std;int main() {    fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV);    const float x=1.1;    const float z=1.123;    float y=x;    for(int j=0;j<90000000;j++)    {        y*=x;        y/=z;        y+=0;        y-=0;    }    return 0;}
Reference

什么是非規格化浮點數Why does changing 0.1f to 0 slow down performance by 10x?IEEE floating pointFloating pointDenormal number


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美一区二区三区在线| 97色伦亚洲国产| 欧美性xxxx极品hd欧美风情| 亚洲美女喷白浆| 亚洲精品美女久久| 成人黄色大片在线免费观看| 欧美人交a欧美精品| 亚洲成人av资源网| 国产日韩精品在线播放| 久久九九免费视频| 欧美激情国产日韩精品一区18| 国产精品福利网| 亚洲丝袜在线视频| 精品久久久久久久久久ntr影视| 日韩精品免费在线| 精品一区二区三区三区| 欧美日韩中文字幕| 777777777亚洲妇女| 97国产真实伦对白精彩视频8| 久久精品91久久香蕉加勒比| 久久久久久国产精品久久| 亚洲高清福利视频| 一本色道久久综合狠狠躁篇的优点| 成人黄色免费网站在线观看| 国产一区二区动漫| 一区二区三区无码高清视频| 国产欧美日韩亚洲精品| 欧美黑人巨大xxx极品| 国产亚洲激情视频在线| 丝袜美腿亚洲一区二区| 国产精品久久久久久久av大片| 欧美大尺度电影在线观看| 亚洲a在线播放| 国产精品美腿一区在线看| 国产一区二区日韩精品欧美精品| 亚洲国产精品yw在线观看| 国产成人精品最新| 欧美精品一区三区| 欧洲精品毛片网站| 久久免费视频网站| 久久精品成人欧美大片| 久久久久国产精品免费网站| 国产日韩欧美中文在线播放| 一本色道久久88亚洲综合88| 中文字幕欧美日韩在线| 亚洲欧美日韩第一区| 国模gogo一区二区大胆私拍| 精品视频久久久| 亚洲高清久久久久久| 亚洲国产天堂久久国产91| 欧美精品精品精品精品免费| 91精品视频在线看| 九九精品视频在线观看| 国产精品99久久久久久人| 亚洲天堂男人天堂| 欧美在线激情网| 91精品国产91久久久久福利| 欧美日韩性视频在线| 国产精品专区一| 国产精品久久久久影院日本| 久久6精品影院| 国产女精品视频网站免费| 国产专区精品视频| 久久久精品亚洲| 国产999精品| 亚洲视频视频在线| 久久亚洲综合国产精品99麻豆精品福利| 欧美激情一二区| 精品视频中文字幕| 亚洲人精品午夜在线观看| 久久久影视精品| 国产有码在线一区二区视频| 日韩在线视频导航| 欧美精品免费在线观看| 成人国产亚洲精品a区天堂华泰| 欧美中文在线免费| 青草青草久热精品视频在线观看| 欧美另类暴力丝袜| 伊人久久精品视频| 精品国偷自产在线视频| 精品久久久久人成| 高跟丝袜一区二区三区| 伊人激情综合网| 欧美成人三级视频网站| 91欧美视频网站| 日本91av在线播放| 中文字幕欧美精品日韩中文字幕| 亚洲欧美成人精品| 日韩电影大片中文字幕| 一区二区三区在线播放欧美| 国模视频一区二区三区| 久久精品国产一区| 91在线免费观看网站| 日韩精品视频观看| 亚洲欧美中文日韩在线v日本| 国产精品成人aaaaa网站| 国产视频丨精品|在线观看| 最新91在线视频| 性视频1819p久久| 美女福利精品视频| 久久久久久久久久久亚洲| 91在线中文字幕| y97精品国产97久久久久久| 久久精品亚洲国产| 国产精品第一区| 欧美性xxxxxxx| 欧美极品少妇xxxxⅹ裸体艺术| 色综合久久久久久中文网| 欧洲午夜精品久久久| 精品一区二区电影| 日韩中文字幕免费视频| 国产美女久久久| 国产精品爽爽爽爽爽爽在线观看| 国产999精品久久久影片官网| 成人激情视频在线播放| 欧美日韩成人黄色| 91福利视频在线观看| 成人伊人精品色xxxx视频| 8090理伦午夜在线电影| 国产午夜精品全部视频在线播放| 91社区国产高清| 亚洲成人教育av| 久久久久久国产精品三级玉女聊斋| 九九热精品视频在线播放| 国产精品久久久久久久久粉嫩av| 福利视频导航一区| 日韩成人av在线播放| 92版电视剧仙鹤神针在线观看| 欧美黑人巨大精品一区二区| 欧美性猛交xxxx乱大交极品| 亚洲天天在线日亚洲洲精| 国产成人福利夜色影视| 91国产精品视频在线| 久久久精品国产| 亚洲片国产一区一级在线观看| 久久久精品久久久| 欧洲中文字幕国产精品| 欧美性猛交xxxx乱大交| 欧美高清理论片| 秋霞成人午夜鲁丝一区二区三区| 午夜精品久久久久久99热| 91丨九色丨国产在线| 欧美日韩国产中字| 欧美在线视频免费观看| 尤物九九久久国产精品的特点| 日韩精品在线视频| 欧美成人精品在线播放| 亚洲二区中文字幕| 亚洲国产精品热久久| 在线电影欧美日韩一区二区私密| 国产精品99久久久久久www| 亚洲国产小视频在线观看| 爽爽爽爽爽爽爽成人免费观看| 日韩中文字幕久久| 精品国产欧美一区二区三区成人| 欧美又大又硬又粗bbbbb| 亚洲一级一级97网| 亚洲精品国产精品国自产观看浪潮| 国产999精品视频| 国产成人一区二区三区| 亚洲性av网站| 亚洲永久免费观看| 亚洲一区二区国产| 91午夜理伦私人影院|