प्रोग्रामेटिक रूप से कैश लाइन का आकार प्राप्त करें?


177

सभी प्लेटफ़ॉर्म आपका स्वागत करते हैं, कृपया अपने उत्तर के लिए प्लेटफ़ॉर्म निर्दिष्ट करें।

इसी तरह का सवाल: प्रोग्राम ++ में C ++ में CPU कैश पेज साइज कैसे प्राप्त करें?


8
FWIW, C ++ 17 इस का एक संकलन-समय प्रदान करेगा: stackoverflow.com/questions/39680206/…
GManNickG

C / C ++ के लिए अलग, यदि आप ऐसी जानकारी प्राप्त करने के लिए असेंबली का उपयोग करने में कोई आपत्ति नहीं करेंगे, तो आप SDL2 के स्रोत कोड में एक नज़र डाल सकते हैं (नेगामार्टिन के उत्तर से जानकारी का विस्तार करते हुए) SDL_GetCPUCacheLineSize, तो एक नज़र डालें cpuid macroजिसमें प्रत्येक के लिए असेंबली सोर्स कोड है प्रोसेसर मॉडल का। आप imgur.com/a/KP57m6s पर नज़र डाल सकते हैं , या सीधे स्रोत पर नज़र डाल सकते हैं ।
12

जवाबों:


186

लिनक्स पर (यथोचित हाल के कर्नेल के साथ), आप इस जानकारी को / sys से प्राप्त कर सकते हैं:

/sys/devices/system/cpu/cpu0/cache/

इस निर्देशिका में कैश के प्रत्येक स्तर के लिए एक उपनिर्देशिका है। उन निर्देशिकाओं में से प्रत्येक में निम्नलिखित फाइलें हैं:

coherency_line_size
level
number_of_sets
physical_line_partition
shared_cpu_list
shared_cpu_map
size
type
ways_of_associativity

यह आपको कैश के बारे में अधिक जानकारी देता है, तो आप कभी भी कैशलाइन आकार ( coherency_line_size) के साथ-साथ सीपीयू इस कैश को क्या साझा करते हैं, यह जानने की उम्मीद करेंगे। यह बहुत उपयोगी है अगर आप साझा किए गए डेटा के साथ मल्टीथ्रेडेड प्रोग्रामिंग कर रहे हैं (आपको बेहतर परिणाम मिलेंगे यदि थ्रेड साझा करने वाले डेटा भी कैश साझा कर रहे हैं)।


4
कैश लाइन के आकार की कौन सी फाइल है? मैं सुसंगतता मान रहा हूँ_लाइन_साइज़ करें? या physical_line_partition?
paxos1977

27
coherency_line_size
स्पिनफायर

6
यह सुनिश्चित करने के लिए: यह बाइट्स में है, हाँ?
जैकब एम।

6
हां, बाइट में coherency_line_size है।
जॉन Zwinck

4
@android: मैं कोर-आई 5 प्रोसेसर के साथ फेडोरा -18 x64 मशीन का उपयोग करता हूं। मेरे सिस्टम में cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_sizeरिटर्न 64। Index1,2,3 फ़ोल्डरों के लिए भी।
आबिद रहमान के

141

लिनक्स पर sysconf (3) देखें।

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

आप इसे getconf का उपयोग करके कमांड लाइन से भी प्राप्त कर सकते हैं:

$ getconf LEVEL1_DCACHE_LINESIZE
64

4
सरल जवाब सिर्फ सबसे अच्छा कर रहे हैं!
फ्रैंक।

3
@warunapww यह बाइट्स में है।
मार्टन बेमेलिस

आखिरकार! आशा है कि अधिक लोग इस उत्तर को समय की बचत के लिए देखते हैं।
एलिनक्स

118

मैं कुछ कैश लाइन सामान पर काम कर रहा हूं और क्रॉस-प्लेटफ़ॉर्म फ़ंक्शन लिखने की आवश्यकता है। मैंने इसे https://github.com/NickStrupat/CacheLineSize पर github repo के लिए प्रतिबद्ध किया है , या आप बस नीचे दिए गए स्रोत का उपयोग कर सकते हैं। जो आप इसके साथ चाहते हैं वह करने के लिए स्वतंत्र महसूस करें।

#ifndef GET_CACHE_LINE_SIZE_H_INCLUDED
#define GET_CACHE_LINE_SIZE_H_INCLUDED

// Author: Nick Strupat
// Date: October 29, 2010
// Returns the cache line size (in bytes) of the processor, or 0 on failure

#include <stddef.h>
size_t cache_line_size();

#if defined(__APPLE__)

#include <sys/sysctl.h>
size_t cache_line_size() {
    size_t line_size = 0;
    size_t sizeof_line_size = sizeof(line_size);
    sysctlbyname("hw.cachelinesize", &line_size, &sizeof_line_size, 0, 0);
    return line_size;
}

#elif defined(_WIN32)

#include <stdlib.h>
#include <windows.h>
size_t cache_line_size() {
    size_t line_size = 0;
    DWORD buffer_size = 0;
    DWORD i = 0;
    SYSTEM_LOGICAL_PROCESSOR_INFORMATION * buffer = 0;

    GetLogicalProcessorInformation(0, &buffer_size);
    buffer = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)malloc(buffer_size);
    GetLogicalProcessorInformation(&buffer[0], &buffer_size);

    for (i = 0; i != buffer_size / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ++i) {
        if (buffer[i].Relationship == RelationCache && buffer[i].Cache.Level == 1) {
            line_size = buffer[i].Cache.LineSize;
            break;
        }
    }

    free(buffer);
    return line_size;
}

#elif defined(linux)

#include <stdio.h>
size_t cache_line_size() {
    FILE * p = 0;
    p = fopen("/sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size", "r");
    unsigned int i = 0;
    if (p) {
        fscanf(p, "%d", &i);
        fclose(p);
    }
    return i;
}

#else
#error Unrecognized platform
#endif

#endif

15
लिनक्स के लिए sysconf (_SC_LEVEL1_DCACHE_LINESIZE) का उपयोग करना बेहतर हो सकता है।
मैट

@ मैट क्यों? बस उत्सुक :-)।
user35915

31

X86 पर, आप कैश और टीएलबी के विभिन्न गुणों को निर्धारित करने के लिए फ़ंक्शन 2 के साथ सीपीयूआईडी अनुदेश का उपयोग कर सकते हैं । फ़ंक्शन 2 का आउटपुट पार्स करना कुछ जटिल है, इसलिए मैं आपको Intel प्रोसेसर आइडेंटिफिकेशन और CPUID इंस्ट्रक्शन (PDF) के सेक्शन 3.1.3 का संदर्भ दूंगा ।

इस डेटा को C / C ++ कोड से प्राप्त करने के लिए, आपको सीपीयूआई अनुदेश करने के लिए इनलाइन असेंबली, कंपाइलर इंट्रिंसिक्स का उपयोग करना होगा या बाहरी असेंबली फ़ंक्शन को कॉल करना होगा।


किसी को कैसे कैश में बनाया के साथ अन्य प्रोसेसर के साथ यह करने के बारे में पता है?
paxos1977

3
@ceretullis: Errr ... x86 ने कैश में बनाया है। क्या "अन्य प्रोसेसर" आप विशेष रूप से देख रहे हैं? आप जो मांग रहे हैं वह प्लेटफॉर्म पर निर्भर है।
बिली ओनेल

9

यदि आप SDL2 का उपयोग कर रहे हैं, तो आप इस फ़ंक्शन का उपयोग कर सकते हैं:

int SDL_GetCPUCacheLineSize(void);

जो बाइट्स में L1 कैश लाइन के आकार का रिटर्न देता है।

मेरी x86_64 मशीन में, यह कोड स्निपेट चल रहा है:

printf("CacheLineSize = %d",SDL_GetCPUCacheLineSize());

का उत्पादन CacheLineSize = 64

मुझे पता है कि मुझे थोड़ी देर हो गई है, लेकिन भविष्य के आगंतुकों के लिए जानकारी जोड़ रहा हूं। एसडीएल प्रलेखन वर्तमान में कहता है कि लौटा संख्या KB में है, लेकिन यह वास्तव में बाइट्स में है।


ओह मेरी यह वास्तव में मददगार है। मैं SDL2 में कुछ खेल लिखने जा रहा हूँ, इसलिए यह वास्तव में उपयोगी होने जा रहा है
निकोलस हम्फ्री

7

विंडोज प्लेटफॉर्म पर:

से http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx

GetLogicalProcessorInformation फ़ंक्शन आपको सिस्टम द्वारा उपयोग किए जाने वाले तार्किक प्रोसेसर की विशेषताएं देगा। आप फ़ंक्शन द्वारा टाइप किए गए System_LOGICAL_PROCESSOR_INFORMATION पर चल सकते हैं, जैसे कि RelationCache की प्रविष्टियाँ। प्रत्येक ऐसी प्रविष्टि में एक ProcessorMask होता है जो आपको बताता है कि कौन सा प्रोसेसर (ओं) पर प्रविष्टि लागू होती है, और CACHE_DESCRIPTOR में, यह बताता है कि किस प्रकार की कैश का वर्णन किया जा रहा है और उस कैश के लिए कैश लाइन कितनी बड़ी है।


4

ARMv6 और इसके बाद के संस्करण C0या कैश प्रकार रजिस्टर है। हालाँकि, यह केवल विशेषाधिकार प्राप्त मोड में उपलब्ध है।

उदाहरण के लिए, कोर्टेक्स ™-ए 8 तकनीकी संदर्भ मैनुअल से :

कैश प्रकार रजिस्टर का उद्देश्य बाइट्स में निर्देश और डेटा कैश न्यूनतम लाइन लंबाई निर्धारित करने के लिए है, ताकि पते की एक श्रेणी अमान्य हो सके।

कैश प्रकार रजिस्टर है:

  • एक केवल पढ़ने के लिए रजिस्टर
  • केवल विशेषाधिकार प्राप्त मोड में सुलभ।

कैश प्रकार रजिस्टर की सामग्री विशिष्ट कार्यान्वयन पर निर्भर करती है। चित्र 3-2 कैश प्रकार रजिस्टर की थोड़ी व्यवस्था दिखाता है ...


मान लें कि एआरएम प्रोसेसर में कैश नहीं है (जाहिर है, कुछ को एक के बिना कॉन्फ़िगर किया जा सकता है)। इसे निर्धारित करने का मानक तरीका है C0। से एआरएम एआरएम , पेज B6-6:

ARMv6 से, सिस्टम कंट्रोल कॉप्रोसेसर Cache टाइप रजिस्टर L1 कैश को परिभाषित करने के लिए अनिवार्य तरीका है, पेज B6-14 पर Cache टाइप रजिस्टर देखें। यह आर्किटेक्चर के पहले वेरिएंट के लिए अनुशंसित विधि भी है। इसके अलावा, पृष्ठ B6-12 पर कैश के अतिरिक्त स्तरों के लिए विचार स्तर 2 कैश समर्थन के लिए आर्किटेक्चर दिशानिर्देशों का वर्णन करता है।


3

आप कुछ समय को मापने के द्वारा इसे प्रोग्राम करने की कोशिश भी कर सकते हैं। जाहिर है, यह हमेशा उतना सटीक नहीं होगा जितना कि स्पष्ट और पसंद, लेकिन यह अधिक पोर्टेबल है। ATLAS इसे अपने कॉन्फ़िगरेशन चरण में करता है, आप इसे देखना चाहते हैं:

http://math-atlas.sourceforge.net/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.