2016-08-31 21 views
7

हमारे पास एक साधारण मेमोरी थ्रूपुट बेंचमार्क है। यह सब स्मृति के एक बड़े ब्लॉक के लिए बार-बार memcpy है।एकल-थ्रेडेड मेमोरी थ्रूपुट के लिए ब्रॉडवेल-ई की तुलना में स्काइलेक इतना बेहतर क्यों है?

कुछ अलग मशीनों पर परिणाम (64-बिट के लिए संकलित) को देखते हुए, स्काइलेक मशीन ओएस (विन 10-64), प्रोसेसर की गति और रैम स्पीड (डीडीआर 4-2133) रखते हुए ब्रॉडवेल-ई की तुलना में काफी बेहतर होती है। वही। हम कुछ प्रतिशत अंक, पर बात नहीं कर रहे हैं बल्कि लगभग 2 के कारक हैं। स्काइलेक को दोहरी चैनल कॉन्फ़िगर किया गया है, और ब्रॉडवेल-ई के परिणाम दोहरी/ट्रिपल/क्वाड-चैनल के लिए भिन्न नहीं हैं।

कोई विचार यह क्यों हो रहा है? कोड इस प्रकार है कि VS2015 में रिलीज में संकलित किया गया है, और रिपोर्ट औसत समय में प्रत्येक memcpy पूरा करने के लिए:

64-बिट: Skylake के लिए 2.2ms Broadwell ई

32-बिट के लिए 4.5ms बनाम : ब्रॉडवेल-ई के लिए स्काइलेक बनाम 3.5 एमएमएस के लिए 2.2 एमएमएस।

हम एक ट्रैक्टर-चैनल Broadwell-ई से अधिक थ्रेड का उपयोग करके निर्माण पर अधिक से अधिक स्मृति throughput प्राप्त कर सकते हैं, और कहा कि अच्छा है, लेकिन देखने के लिए एकल पिरोया स्मृति पहुँच के लिए इस तरह के एक कठोर अंतर निराशा होती है। कोई विचार क्यों अंतर इतना स्पष्ट है?

हमने विभिन्न बेंचमार्किंग सॉफ़्टवेयर का भी उपयोग किया है, और वे यह सरल उदाहरण दिखाते हैं कि एकल-थ्रेडेड मेमोरी थ्रूपुट स्किलेक पर बेहतर तरीका है।

#include <memory> 
#include <Windows.h> 
#include <iostream> 

//Prevent the memcpy from being optimized out of the for loop 
_declspec(noinline) void MemoryCopy(void *destinationMemoryBlock, void *sourceMemoryBlock, size_t size) 
{ 
    memcpy(destinationMemoryBlock, sourceMemoryBlock, size); 
} 

int main() 
{ 
    const int SIZE_OF_BLOCKS = 25000000; 
    const int NUMBER_ITERATIONS = 100; 
    void* sourceMemoryBlock = malloc(SIZE_OF_BLOCKS); 
    void* destinationMemoryBlock = malloc(SIZE_OF_BLOCKS); 
    LARGE_INTEGER Frequency; 
    QueryPerformanceFrequency(&Frequency); 
    while (true) 
    { 
     LONGLONG total = 0; 
     LONGLONG max = 0; 
     LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds; 
     for (int i = 0; i < NUMBER_ITERATIONS; ++i) 
     { 
      QueryPerformanceCounter(&StartingTime); 
      MemoryCopy(destinationMemoryBlock, sourceMemoryBlock, SIZE_OF_BLOCKS); 
      QueryPerformanceCounter(&EndingTime); 
      ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; 
      ElapsedMicroseconds.QuadPart *= 1000000; 
      ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; 
      total += ElapsedMicroseconds.QuadPart; 
      max = max(ElapsedMicroseconds.QuadPart, max); 
     } 
     std::cout << "Average is " << total*1.0/NUMBER_ITERATIONS/1000.0 << "ms" << std::endl; 
     std::cout << "Max is " << max/1000.0 << "ms" << std::endl; 
    } 
    getchar(); 
} 
+0

MSVC के memcpy पुस्तकालय समारोह CPUID या कुछ भी पर आधारित एक रणनीति चुनाव करता है? जैसे AVX पाश बनाम 'rep movsb'? क्या आप सुनिश्चित करते हैं कि दोनों बफर कम से कम 64 बी-सभी परीक्षणों के लिए गठबंधन हैं? क्या आपने पेर्फ काउंटरों को यह देखने के लिए जांच की है कि क्या आपको कोई टीएलबी याद आ रही है, या सिर्फ एल 3 कैश याद आती है? (स्काइलेक समानांतर में दो टीएलबी चल सकता है)। क्या आपका ब्रॉडवेल-ई एक बहु-सॉकेट सिस्टम (NUMA) है? –

+0

क्या आपने यह सुनिश्चित करने के लिए अपने ब्रॉडवेल सिस्टम पर BIOS की जांच की है कि इसमें प्रीफेचिंग अक्षम या कुछ भी नहीं है? क्या आप अन्य ब्रॉडवेल या हैसवेल डेस्कटॉप सिस्टम की तुलना करने में सक्षम थे? (जिस विशिष्ट ब्रॉडवेल मशीन पर आप परीक्षण कर रहे हैं उस पर कुछ अजीब बात करें)। 23.8MiB कॉपी करने के लिए –

+1

2.2ms मिश्रित पढ़ने + लिखने के लिए, के बारे में 10.6GiB/s पढ़ने की और लिखने प्रत्येक है। इंटेल का कहना है [Skylake i5-6600] (http://ark.intel.com/products/88188) (और अन्य एसकेएल मॉडल DDR4-2133 का प्रयोग करके) एक सैद्धांतिक अधिकतम स्मृति बैंडविड्थ 34.1 जीबी/s (या 31.8 के GiB/है रों)। इसलिए यदि प्रत्येक भार और स्टोर एल 3 में चूक जाता है और उसे मुख्य स्मृति में जाना पड़ता है, तो यह सैद्धांतिक अधिकतम के लगभग 2/3s है। हालांकि, एक धागे के लिए यह सामान्य हो सकता है। –

उत्तर

2

एकल पिरोया स्मृति बैंडविड्थ, DRAM नियंत्रक बाधाओं से नहीं प्रणाली के आराम करने के L1D से स्थानान्तरण की max_concurrency/latency द्वारा सीमित है। प्रत्येक कोर में 10 लाइन-फिल बफर (एलएफबी) होते हैं जो एल 1 डी से/उत्कृष्ट अनुरोधों को ट्रैक करते हैं। (और 16 "सुपरक्यू" प्रविष्टियां जो एल 2 से/रेखाओं को ट्रैक करती हैं)।

इंटेल के कई कोर चिप्स में क्वाड-कोर या ड्यूल-कोर डेस्कटॉप/लैपटॉप चिप्स की तुलना में एल 3/मेमोरी की उच्च विलंबता है, इसलिए एकल-थ्रेडेड मेमोरी बैंडविड्थ वास्तव में एक बड़े ज़ीऑन पर बहुत खराब है, भले ही अधिकतम कुल बैंडविड्थ कई धागे के साथ बहुत बेहतर है। उनके पास रिंग बस पर कई और होप्स हैं जो कोर, मेमोरी कंट्रोलर और सिस्टम एजेंट (पीसीआईई और इसी तरह) को जोड़ते हैं।

एसकेएक्स (स्काईलेक-सर्वर/AVX512, आई 9 "हाई-एंड डेस्कटॉप" चिप्स समेत) वास्तव में इसके लिए बुरा है: एल 3/मेमोरी विलंबता ब्रॉडवेल-ई/ब्रॉडवेल-ईपी के मुकाबले काफी अधिक है, इसलिए एकल-थ्रेडेड एक समान कोर गिनती के साथ ब्रॉडवेल की तुलना में बैंडविड्थ भी बदतर है। निजी प्रति- शायद भविष्य की पीढ़ियों के छोटे/मध्यम कोर मायने रखता है के लिए बेहतर L3 बैंडविड्थ/विलंबता होगा; (SKX एक जाल के बजाय एक अंगूठी बस की कि बेहतर मापता है क्योंकि उपयोग करता है, see this for details on both लेकिन जाहिरा तौर पर लगातार कारकों नए डिजाइन में बुरा कर रहे हैं।। कोर एल 2 1MiB अप करने के लिए छोड़ रहा है, हालांकि, तो शायद L3 बिजली बचाने के लिए जानबूझकर धीमी है।)


एक ट्रैक्टर या डुअल कोर चिप केवल कुछ धागे की जरूरत है (खासकर अगर कोर + uncore (एल 3) क्लॉक कर रहे हैं उच्च) अपनी मेमोरी बैंडविड्थ को संतृप्त करने के लिए, और तेजी से डीडीआर 4 डुअल चैनल के साथ स्काइलेक में काफी बैंडविड्थ है।

इस बारे में अधिक जानकारी के लिए, 86 स्मृति बैंडविड्थ के बारे में this answer की अदृश्यता बाध्य प्लेटफार्म खंड देखें। (और memcpy के लिए अन्य भागों को पढ़ने/SIMD साथ memset बनाम rep movs/rep stos, और NT भंडार बनाम नियमित RFO स्टोर, आदि लूप।)

भी संबंधित हैं: What Every Programmer Should Know About Memory? (क्या अभी भी सच है पर 2017 अद्यतन और क्या है कि में बदल गया है 2007 से उत्कृष्ट लेख)।

2

मुझे अंत में VTune (evalutation) ऊपर और चल रहा है। यह मेमोरी लेटेंसी से आने वाले ब्रॉडवेल-ई देरी के एक बड़े हिस्से के साथ, स्काइलेक पर ब्रॉडवेल-ई और .324 पर .602 (0 और 1 के बीच) का एक ड्रैम बाध्य स्कोर देता है। यह देखते हुए कि मेमोरी स्टिक्स एक ही गति हैं (स्काइलेक में कॉन्फ़िगर किए गए दोहरे चैनल को छोड़कर और ब्रॉडवेल-ई में क्वाड-चैनल को छोड़कर), मेरा सबसे अच्छा अनुमान यह है कि स्काइलेक में मेमोरी कंट्रोलर के बारे में कुछ बहुत ही बेहतर है।

यह ब्रॉडवेल-ई आर्किटेक्चर में खरीदारी करना बहुत कठिन कॉल करता है, और यह आवश्यक है कि आपको वास्तव में अतिरिक्त कोर की भी आवश्यकता हो।

मुझे एल 3/टीएलबी मिस गिनती भी मिली। ब्रॉडवेल-ई पर, टीएलबी मिस गिनती लगभग 20% अधिक थी, और एल 3 मिस लगभग 36% अधिक है।

मुझे नहीं लगता कि यह वास्तव में "क्यों" का उत्तर है, इसलिए मैं इसे इस तरह चिह्नित नहीं करूंगा, लेकिन जैसा कि मुझे लगता है कि मैं उस समय के लिए एक के पास जाऊंगा। रास्ते में सभी सहायक टिप्पणियों के लिए धन्यवाद। आधुनिक CPUs पर

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

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