一、背景知識
CPU緩存(Cache Memory),是位於CPU與內存之間的臨時存儲器,它的容量比內存小的多但是交換速度卻比內存要快得多。高速緩存的出現主要是為了解決CPU運算速度與內存讀寫速度不匹配的矛盾,因為CPU運算速度要比內存讀寫速度快很多,這樣會使CPU花費很長時間等待數據到來或把數據寫入內存。在緩存中的數據是內存中的一小部分,但這一小部分是短時間內CPU即將訪問的,當CPU調用大量數據時,就可避開內存直接從緩存中調用,從而加快讀取速度。
----以上引自度娘百科,懶吶- -"
緩存中是由緩存行來管理的,典型的緩存行大小為64bytes,一次讀入就是64bytes。即使僅僅想讀入一個Int64,實際上也是將其後的56bytes也讀進來。
因此如果需要操作一個Length為8的Int64數組,一次讀入,次次命中,嗨吧~~
二、栗子
設計了一個小栗子,是累加一個二維Int64的數據:
如果從一維循環,那麼類似於順序讀入,這樣應該能實現1次讀入緩存,後7次命中,性能應該會好一些。
如果從二維循環,那麼讀入一次緩存,後面的就沒辦法命中了,性能一定是底很多。
三、栗子代碼
1 using System; 2 3 namespace PerformanceOfCacheLineTest 4 { 5 class Program 6 { 7 private const Int64 ONE_DIMENSION = 1024 * 1024; 8 private const Int64 TWO_DIMENSION = 64; 9 10 static void Main(string[] args) 11 { 12 Int64[][] array = new Int64[ONE_DIMENSION][]; 13 for (int i = 0; i < ONE_DIMENSION; i++) 14 { 15 array[i] = new Int64[TWO_DIMENSION]; 16 for (int j = 0; j < TWO_DIMENSION; j++) 17 { 18 array[i][j] = 0; 19 } 20 } 21 22 Console.WriteLine("starting...."); 23 24 DateTime start = System.DateTime.Now; 25 Int64 sum = 0; 26 for (int i = 0; i < ONE_DIMENSION; i++) 27 { 28 for (int j = 0; j < TWO_DIMENSION; j++) 29 { 30 sum += array[i][j]; 31 } 32 } 33 DateTime end = System.DateTime.Now; 34 Console.WriteLine("one dimension first: using " + (end - start).TotalMilliseconds); 35 36 37 start = System.DateTime.Now; 38 for (int j = 0; j < TWO_DIMENSION; j++) 39 { 40 for (int i = 0; i < ONE_DIMENSION; i++) 41 { 42 sum += array[i][j]; 43 } 44 } 45 end = System.DateTime.Now; 46 Console.WriteLine("two dimension first: using " + (end - start).TotalMilliseconds); 47 48 Console.WriteLine("...ended"); 49 Console.Read(); 50 } 51 } 52 }
四、栗子結果
五、結論
差距還是很明顯的喲,印證了假設。
作為一枚肉鳥,學到新的東西總是讓人耳目一新,世界觀都不一樣了呢*_*。。。需要學習的東西還很多呀!!!