2011-06-18 9 views
12

मैं .NET की दुनिया में सीपीयू कैश प्रदर्शन के बारे में जानने की कोशिश कर रहा हूं। विशेष रूप से मैं इगोर ओस्तोवस्की के article about Processor Cache Effects के माध्यम से काम कर रहा हूं।प्रदर्शन जब सीपीयू कैश उत्पन्न करता है मिस

मैं अपने लेख में पहले तीन उदाहरणों से गुजर चुका हूं और उन परिणामों को रिकॉर्ड किया है जो उनके से व्यापक रूप से भिन्न हैं। मुझे लगता है कि मुझे कुछ गलत करना होगा क्योंकि मेरी मशीन पर प्रदर्शन उसके लेख में जो दिखाता है उसके लगभग विपरीत विपरीत परिणाम दिखा रहा है। मैं कैश मिस से बड़े प्रभाव नहीं देख रहा हूं जो मुझे उम्मीद है।

मैं क्या गलत कर रहा हूं? (बुरा कोड, संकलक सेटिंग, आदि)

यहाँ मेरी मशीन पर प्रदर्शन परिणाम हैं:

enter image description here

enter image description here

enter image description here

यदि यह मदद करता है, पर प्रोसेसर मेरी मशीन एक इंटेल कोर i7-2630QM है।

enter image description here

मैं 64 रिलीज मोड में संकलित किया है: यहाँ मेरी प्रोसेसर के कैश पर जानकारी है।

class Program 
    { 

     static Stopwatch watch = new Stopwatch(); 

     static int[] arr = new int[64 * 1024 * 1024]; 

     static void Main(string[] args) 
     { 
      Example1(); 
      Example2(); 
      Example3(); 


      Console.ReadLine(); 
     } 

     static void Example1() 
     { 
      Console.WriteLine("Example 1:"); 

      // Loop 1 
      watch.Restart(); 
      for (int i = 0; i < arr.Length; i++) arr[i] *= 3; 
      watch.Stop(); 
      Console.WriteLine("  Loop 1: " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      // Loop 2 
      watch.Restart(); 
      for (int i = 0; i < arr.Length; i += 32) arr[i] *= 3; 
      watch.Stop(); 
      Console.WriteLine("  Loop 2: " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      Console.WriteLine(); 
     } 

     static void Example2() 
     { 

      Console.WriteLine("Example 2:"); 

      for (int k = 1; k <= 1024; k *= 2) 
      { 

       watch.Restart(); 
       for (int i = 0; i < arr.Length; i += k) arr[i] *= 3; 
       watch.Stop(); 
       Console.WriteLine("  K = "+ k + ": " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      } 
      Console.WriteLine(); 
     } 

     static void Example3() 
     { 

      Console.WriteLine("Example 3:"); 

      for (int k = 1; k <= 1024*1024; k *= 2) 
      { 

       //256* 4bytes per 32 bit int * k = k Kilobytes 
       arr = new int[256*k]; 



       int steps = 64 * 1024 * 1024; // Arbitrary number of steps 
       int lengthMod = arr.Length - 1; 

       watch.Restart(); 
       for (int i = 0; i < steps; i++) 
       { 
        arr[(i * 16) & lengthMod]++; // (x & lengthMod) is equal to (x % arr.Length) 
       } 

       watch.Stop(); 
       Console.WriteLine("  Array size = " + arr.Length * 4 + " bytes: " + (int)(watch.Elapsed.TotalMilliseconds * 1000000.0/arr.Length) + " nanoseconds per element"); 

      } 
      Console.WriteLine(); 
     } 

    } 
+0

आप किस सीपीयू का उपयोग कर रहे हैं? इसमें कितना कैश है? स्तर 1 और 2? – Oded

+0

यह एक इंटेल कोर i7-2630QM है। कैश आंकड़े उपरोक्त कमांड लाइन छवि में हैं। –

+0

इसके अलावा, आपके पास सिस्टम में पर्याप्त रैम है? आप परीक्षण के दौरान पेजफाइल पर थ्रैशिंग नहीं कर रहे हैं? –

उत्तर

3

क्यों आप मैं दूसरी पाश में उपयोग कर रहे हैं + = 32:

नीचे मेरी स्रोत कोड है। आप इस तरह से कैश लाइनों पर कदम उठा रहे हैं। 32 * 4 = 128 बाइट्स बड़ा तो 64bytes की आवश्यकता है।

+1

... मुझे यह जवाब समझ में नहीं आता है। ऑर्डर-ऑफ-आयाम अंतर के लिए वह खाता क्यों है, और उसे दूसरे या तीसरे परीक्षणों के साथ क्या करना है? –

+0

यह भी जानते हुए कि यह किसी और के संदर्भ में काफी पुराना है, कैश लाइन आम तौर पर 64 बाइट्स के हिस्सों में लाई जाती है, इसलिए दीवान क्या दिखा रहा है कि ** ** ** ** (4 बाइट्स) सरणी में, चाहे आप इसे पार करते हों 32 से कदम उठाने पर आप एक से अधिक कैश लाइन पर कूदना समाप्त कर देंगे, यदि आप 32 (16x4 = 64) के बजाय 16 का उपयोग कर रहे थे, तो आप लूप 2 तेज़ी से क्या करेंगे, फिर आप किसी भी कैश लाइन और लूप को नहीं छोड़ेंगे 1 और 2 का एक समान परिणाम होगा, यहां तक ​​कि लूप 2 लूप 1 की तुलना में कम बार दोहराएगा। – DenninDalke

संबंधित मुद्दे