青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

loop_in_codes

低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

為什么處理排序的數組要比非排序的快?

參考Why is processing a sorted array faster than an unsorted array?

問題

看以下代碼:

#include <algorithm>
#include <ctime>
#include <iostream>

int main()
{
    // generate data
    const unsigned arraySize = 32768;
    int data[arraySize];

    for (unsigned c = 0; c < arraySize; ++c)
        data[c] = std::rand() % 256;


    // !!! with this, the next loop runs faster
    std::sort(data, data + arraySize);


    // test
    clock_t start = clock();
    long long sum = 0;

    for (unsigned i = 0; i < 100000; ++i)
    {
        // primary loop
        for (unsigned c = 0; c < arraySize; ++c)
        {
            if (data[c] >= 128)
                sum += data[c];
        }
    }

    double elapsedTime = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;

    std::cout << elapsedTime << std::endl;
    std::cout << "sum = " << sum << std::endl;
}

問題就在于,去掉std::sort那一行,以上代碼將運行更長的時間。在我的機器上未去掉std::sort耗時8.99s,去掉后耗時24.78s。編譯器使用的是gcc4.4.3。事實上,以上代碼跟編譯器沒有關系,甚至跟語言沒有關系。那這是為什么呢?

這跟處理這個數組的邏輯有非常大的關系。如以上代碼所示,這個循環里有個條件判斷。條件判斷被編譯成二進制代碼后,就是一個跳轉指令,類似:

具體為什么會不同,這涉及到計算機CPU執行指令時的行為。

CPU的流水線指令執行

想象現在有一堆指令等待CPU去執行,那么CPU是如何執行的呢?具體的細節可以找一本計算機組成原理的書來看。CPU執行一堆指令時,并不是單純地一條一條取出來執行,而是按照一種流水線的方式,在CPU真正執行一條指令前,這條指令就像工廠里流水線生產的產品一樣,已經被經過一些處理。簡單來說,一條指令可能經過這些過程:取指(Fetch)、解碼(Decode)、執行(Execute)、放回(Write-back)。

假設現在有指令序列ABCDEFG。當CPU正在執行(execute)指令A時,CPU的其他處理單元(CPU是由若干部件構成的)其實已經預先處理到了指令A后面的指令,例如B可能已經被解碼,C已經被取指。這就是流水線執行,這可以保證CPU高效地執行指令。

Branch Prediction

如上所說,CPU在執行一堆順序執行的指令時,因為對于執行指令的部件來說,其基本不需要等待,因為諸如取指、解碼這些過程早就被做了。但是,當CPU面臨非順序執行的指令序列時,例如之前提到的跳轉指令,情況會怎樣呢?

取指、解碼這些CPU單元并不知道程序流程會跳轉,只有當CPU執行到跳轉指令本身時,才知道該不該跳轉。所以,取指解碼這些單元就會繼續取跳轉指令之后的指令。當CPU執行到跳轉指令時,如果真的發生了跳轉,那么之前的預處理(取指、解碼)就白做了。這個時候,CPU得從跳轉目標處臨時取指、解碼,然后才開始執行,這意味著:CPU停了若干個時鐘周期!

這其實是個問題,如果CPU的設計放任這個問題,那么其速度就很難提升起來。為此,人們發明了一種技術,稱為branch prediction,也就是分支預測。分支預測的作用,就是預測某個跳轉指令是否會跳轉。而CPU就根據自己的預測到目標地址取指令。這樣,即可從一定程度提高運行速度。當然,分支預測在實現上有很多方法。

簡單的預測可以直接使用之前的實際執行結果。例如某個跳轉指令某一次產生了跳轉,那么下一次執行該指令時,CPU就直接從跳轉目標地址處取指,而不是該跳轉指令的下一條指令。

答案

了解了以上信息后,文章開頭提出的問題就可以解釋了。這個代碼中有一個循環,這個循環里有一個條件判斷。每一次CPU執行這個條件判斷時,CPU都可能跳轉到循環開始處的指令,即不執行if后的指令。使用分支預測技術,當處理已經排序的數組時,在若干次data[c]>=128都不成立時(或第一次不成立時,取決于分支預測的實現),CPU預測這個分支是始終會跳轉到循環開始的指令時,這個時候CPU將保持有效的執行,不需要重新等待到新的地址取指;同樣,當data[c]>=128條件成立若干次后,CPU也可以預測這個分支是不必跳轉的,那么這個時候CPU也可以保持高效執行。

相反,如果是無序的數組,CPU的分支預測在很大程度上都無法預測成功,基本就是50%的預測成功概率,這將消耗大量的時間,因為CPU很多時間都會等待取指單元重新取指。

本文完。最后感嘆下stackoverflow上這個帖子里那個老外回答問題的專業性,我要是樓主早就感動得涕淚橫飛了。感謝每一個傳播知識的人。

參考資料

  1. http://blog.sina.com.cn/s/blog_6c673e570100zfmo.html
  2. http://www.cnblogs.com/dongliqian/archive/2012/04/05/2433847.html
  3. http://en.wikipedia.org/wiki/Branch_predictor

posted on 2012-08-30 17:43 Kevin Lynx 閱讀(3102) 評論(3)  編輯 收藏 引用 所屬分類: c/c++other

評論

# re: 為什么處理排序的數組要比非排序的快?[未登錄] 2012-08-30 18:12 sand

so professional!, nice job!  回復  更多評論   

# re: 為什么處理排序的數組要比非排序的快? 2012-08-30 19:30 畢達哥拉斯半圓

答案是很簡單的,但是回答的太專業了,而且還配了張圖片,這人多有空啊!閑的  回復  更多評論   

# re: 為什么處理排序的數組要比非排序的快? 2012-09-01 09:50 liyou

看不到圖  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            韩日成人av| 欧美久久久久免费| 黄色亚洲网站| 久久香蕉国产线看观看av| 久久久精品免费视频| 亚洲国产福利在线| 日韩视频一区二区三区在线播放| 欧美极品在线播放| 亚洲一二三区在线观看| 亚洲在线免费视频| 极品尤物av久久免费看 | 加勒比av一区二区| 亚洲第一免费播放区| 欧美成人国产一区二区| 亚洲最新在线| 久久精品国产综合| 一本高清dvd不卡在线观看| 亚洲一区二区少妇| 久久av二区| 亚洲伦理在线| 午夜精品在线视频| 91久久精品一区二区别| 亚洲女性裸体视频| 亚洲国产合集| 亚洲欧美日韩国产综合精品二区| 精品999久久久| 亚洲视频一区二区在线观看| 欲色影视综合吧| 一区二区三区日韩在线观看| 在线电影院国产精品| 99re6热在线精品视频播放速度| 国产一区二区黄| 一本色道久久综合一区| 亚洲东热激情| 欧美一级在线亚洲天堂| 中文网丁香综合网| 美女性感视频久久久| 欧美一区二区三区免费视频| 欧美jjzz| 欧美激情精品久久久久久黑人 | 制服丝袜亚洲播放| 久久亚洲国产精品一区二区| 亚洲欧美一区在线| 欧美精品一区二区三区久久久竹菊| 久久久久久久欧美精品| 国产精品多人| 日韩亚洲国产欧美| 亚洲另类在线视频| 免费的成人av| 欧美大片在线观看一区| 国内精品久久久久久久影视麻豆| 一本色道久久99精品综合| 亚洲精品一区二区三| 久久久女女女女999久久| 久久精品一区二区三区不卡牛牛| 欧美午夜在线视频| 日韩午夜av| 中文精品在线| 欧美日韩一区二区三区在线观看免| 亚洲高清资源综合久久精品| 亚洲国产精品成人综合色在线婷婷| 久久丁香综合五月国产三级网站| 欧美在线亚洲| 黄色成人av在线| 久久久xxx| 欧美成人精品h版在线观看| 永久91嫩草亚洲精品人人| 久久精品欧美| 亚洲成人在线视频网站| 亚洲精品美女91| 欧美精品九九| 夜夜狂射影院欧美极品| 亚洲自拍另类| 国产婷婷97碰碰久久人人蜜臀| 性久久久久久久久| 美女网站久久| 日韩午夜在线视频| 国产精品久久久久久一区二区三区| 亚洲小说欧美另类社区| 久久精品亚洲一区二区| …久久精品99久久香蕉国产| 蜜臀av国产精品久久久久| 亚洲精品美女在线观看| 国产精品美女一区二区在线观看 | 欧美顶级艳妇交换群宴| 欧美色一级片| 欧美电影免费观看高清完整版| 亚洲国产精品va| 欧美日韩中文字幕| 欧美一站二站| 91久久精品美女高潮| 亚洲一区二区在线播放| 国内精品一区二区三区| 欧美黄色免费| 欧美在线地址| 亚洲六月丁香色婷婷综合久久| 亚洲欧美色婷婷| 亚洲国产精品久久久久秋霞影院| 欧美久久婷婷综合色| 欧美一区二区三区四区夜夜大片| 欧美刺激性大交免费视频 | 国模吧视频一区| 欧美精品午夜视频| 午夜一区二区三视频在线观看| 欧美国产91| 欧美在线视频日韩| 一本久道综合久久精品| 国产真实久久| 国产精品裸体一区二区三区| 久久亚洲精品视频| 午夜一区二区三区不卡视频| 亚洲精品日韩在线| 媚黑女一区二区| 欧美在线黄色| 亚洲香蕉网站| 日韩一区二区精品视频| 在线观看日韩欧美| 国产模特精品视频久久久久| 欧美日韩大片| 欧美国产一区视频在线观看| 久久精彩视频| 欧美一区二区高清在线观看| 这里只有精品视频| 亚洲精品午夜精品| 欧美激情自拍| 欧美成人午夜激情| 狂野欧美一区| 久久人人爽人人爽爽久久| 亚洲欧美日本日韩| 亚洲小少妇裸体bbw| 一区二区三区视频在线| 亚洲精品一区二区三区蜜桃久| 亚洲大片在线观看| 在线观看一区二区精品视频| 狠狠88综合久久久久综合网| 国产日韩一区| 国产女人水真多18毛片18精品视频| 欧美日韩成人在线观看| 欧美日本韩国一区二区三区| 欧美a级片网站| 欧美国产亚洲另类动漫| 欧美国产高清| 欧美日韩国产综合视频在线| 欧美高清视频| 欧美网站大全在线观看| 国产精品久久久久毛片大屁完整版 | 麻豆国产精品一区二区三区| 久久久久.com| 久久人人爽人人爽| 欧美大胆成人| 欧美日韩一区二区视频在线| 亚洲国产成人在线播放| 亚洲欧美电影在线观看| 性欧美videos另类喷潮| 久久精品人人做人人爽电影蜜月| 欧美一区二区免费| 久久久久久久久久久久久女国产乱 | 久久精品视频免费播放| 久久人人爽国产| 亚洲大胆在线| 99ri日韩精品视频| 小黄鸭视频精品导航| 久久久久国产精品一区三寸| 欧美v日韩v国产v| 欧美日韩午夜剧场| 国产情人节一区| 在线观看欧美成人| aⅴ色国产欧美| 久久精精品视频| 亚洲国产欧美不卡在线观看| 在线一区二区三区四区| 久久精品麻豆| 欧美日韩一区二区免费在线观看| 国产精品伊人日日| 亚洲高清视频在线观看| 亚洲视频在线一区| 另类激情亚洲| 一二三四社区欧美黄| 久久久青草婷婷精品综合日韩| 欧美日韩三区四区| 激情久久综艺| 亚洲欧美另类综合偷拍| 欧美.www| 亚洲欧美另类久久久精品2019| 蜜臀a∨国产成人精品| 国产乱人伦精品一区二区| 亚洲激情女人| 久久久久88色偷偷免费| 亚洲欧洲精品一区二区三区| 欧美在线免费观看| 欧美亚洲不卡| 亚洲破处大片| 久久一区亚洲| 亚洲午夜久久久久久尤物 | 亚洲免费在线精品一区| 女生裸体视频一区二区三区| 国产一区二区三区久久久久久久久| 一本久道久久综合婷婷鲸鱼| 欧美成人免费全部| 久久福利毛片|