自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Code Inside:為什么處理已排序數(shù)組比處理未排序數(shù)組更快?

開發(fā) 后端 開發(fā)工具
現(xiàn)代處理器都支持指令并行處理和超流水線作業(yè)。因此,當(dāng)處理器遇到程序分支時,都會去猜測應(yīng)該走哪一條分支。如果猜對了,程序接著流暢運行。如果猜錯了,則處理器需要做一些額外的工作,再次回到那條正確的分支。

很久以前在stackoverflow上看到下面這段代碼,今天忍不住把它摘錄過來。

  1. #include <algorithm>  
  2. #include <ctime>  
  3. #include <iostream>  
  4.    
  5. int main()  
  6. {  
  7.     // Generate data  
  8.     const unsigned arraySize = 32768;  
  9.     int data[arraySize];  
  10.    
  11.     for (unsigned c = 0; c < arraySize; ++c)  
  12.         data[c] = std::rand() % 256;  
  13.    
  14.     // !!! With this, the next loop runs faster  
  15.     std::sort(data, data + arraySize);  
  16.    
  17.     // Test  
  18.     clock_t start = clock();  
  19.     long long sum = 0;  
  20.    
  21.     for (unsigned i = 0; i < 100000; ++i)  
  22.     {  
  23.         // Primary loop  
  24.         for (unsigned c = 0; c < arraySize; ++c)  
  25.         {  
  26.             if (data[c] >= 128)  
  27.                 sum += data[c];  
  28.         }  
  29.     }  
  30.    
  31.     double elapsedTime = static_cast<double>(clock() - start) / CLOCKS_PER_SEC;  
  32.    
  33.     std::cout << elapsedTime << std::endl;  
  34.     std::cout << "sum = " << sum << std::endl;  

上面的程序在保留std::sort(data, data + arraySize);語句時,程序運行時間是1.93 

但去掉排序語句后,程序運行時間是11.54

問題:為什么會出現(xiàn)這種情況?

解答分支預(yù)測。

[[119029]]

程序分支

考慮以下if語句塊。對于處理器來說,就是一個分支指令,如下:

處理器每次遇到一條分支時,它都不知道該走哪一條道。這時候該怎么辦?程序停下來,等待前面的指令執(zhí)行完,得到確切的結(jié)果后,再接著走某一條分支。

現(xiàn)代處理器都支持指令并行處理和超流水線作業(yè)。因此,當(dāng)處理器遇到程序分支時,都會去猜測應(yīng)該走哪一條分支。

如果猜對了,程序接著流暢運行。如果猜錯了,則處理器需要做一些額外的工作,再次回到那條正確的分支。

因此,如果處理器每次都猜錯,那程序的運行時間就會邊長。

這就是上面的代碼為什么運行時間會相差那么大的原因。

對于分支語句:

  1. if (data[c] >= 128)  
  2.     sum += data[c]; 

在保留std::sort(data, data + arraySize);的情況下。數(shù)組data中的內(nèi)容是這樣的:

  1. T = branch taken  
  2. N = branch not taken  
  3.    
  4. data[] = 01234, ... 126127128129130, ... 250251252, ...  
  5. branch = N  N  N  N  N  ...   N    N    T    T    T  ...   T    T    T  ...  
  6.    
  7.        = NNNNNNNNNNNN ... NNNNNNNTTTTTTTTT ... TTTTTTTTTT  (easy to predict) 

在未排序的情況下,數(shù)組data中的內(nèi)容是這樣的:

  1. data[] = 22618512515819814421779202118,  14150177182133, ...  
  2. branch =   T,   T,   N,   T,   T,   T,   T,  N,   T,   N,   N,   T,   T,   T,   N  ...  
  3.    
  4.        = TTNTTTTNTNNTTTN ...   (completely random - hard to predict) 

也就是說,在已經(jīng)排序的情況下,處理器便能更好的預(yù)測分支了。因此,程序也運行的更快。

關(guān)于分支預(yù)測

閱讀linux源代碼時,你會發(fā)現(xiàn)if(likely( )){}或是if(unlikely( ))這樣的語句。對于條件選擇語句,gcc內(nèi)建了一條指令用于優(yōu)化,在一個條件經(jīng)常出現(xiàn),或者該條件很少出現(xiàn)的時候,編譯器可以根據(jù)這條指令對條件分支選擇進(jìn)行優(yōu)化。而Linux內(nèi)核把這條指令封裝成了宏likely()和unlikely()。

因此,在編寫程序時,如果一個分支條件只有在很少數(shù)的情況下才出現(xiàn)時,我們使用unlikely( )和likely( )能夠加快程序的運行,這也是一種優(yōu)化程序的手段。

比如這樣:

  1. if ( unlikely(statement) ) { //這里便是告訴編譯器,這個條件只在少數(shù)情況下發(fā)生  
  2.  
  3. dosomething();  
  4.  

原文鏈接:http://www.cricode.com/3347.html

責(zé)任編輯:林師授 來源: 快課網(wǎng)
相關(guān)推薦

2020-10-15 12:30:37

Python編程語言

2021-10-18 11:29:48

奇偶排序數(shù)組數(shù)據(jù)結(jié)構(gòu)算法

2021-11-08 23:09:07

Go排序數(shù)據(jù)

2021-01-13 10:51:08

PromissetTimeout(函數(shù)

2009-11-16 16:17:45

PHP數(shù)組排序

2009-11-16 17:35:38

PHP數(shù)組排序

2021-11-02 14:54:41

排序數(shù)組元素

2021-12-13 11:31:36

排序數(shù)組數(shù)據(jù)結(jié)構(gòu)算法

2009-08-13 10:35:05

Scala數(shù)組排序

2009-11-30 18:59:52

PHP數(shù)組排序

2017-04-06 14:10:08

JavaScript數(shù)組排序

2021-11-17 08:43:17

LeetCode有序數(shù)組算法

2021-07-05 06:39:59

經(jīng)典算法無序數(shù)組

2021-09-07 11:01:41

二叉搜索樹序數(shù)組

2023-09-14 15:48:53

排序測試

2020-12-07 15:16:04

排序算法

2009-11-20 09:24:10

PHP多維數(shù)組排序

2009-11-24 10:31:22

PHP函數(shù)sort()

2009-11-18 11:30:26

PHP數(shù)組排序

2009-11-25 09:56:06

PHP數(shù)組處理函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號