รับขนาดบรรทัดแคชโดยทางโปรแกรมหรือไม่


177

ยินดีต้อนรับทุกแพลตฟอร์มโปรดระบุแพลตฟอร์มสำหรับคำตอบของคุณ

คำถามที่คล้ายกัน: วิธีการรับขนาดหน้าแคช CPU โดยทางโปรแกรมโดยทางโปรแกรม


8
FWIW, C ++ 17 จะให้การประมาณเวลาคอมไพล์ของเรื่องนี้: stackoverflow.com/questions/39680206//
GManNickG

นอกเหนือจาก C / C ++ หากคุณไม่สนใจการใช้แอสเซมบลีเพื่อรับข้อมูลคุณสามารถดู (ขยายข้อมูลจากคำตอบของ negamartin) ที่SDL_GetCPUCacheLineSizeฟังก์ชั่นซอร์สโค้ดของ SDL2 จากนั้นลองดูที่cpuid macroมีซอร์สโค้ดประกอบสำหรับแต่ละ ของโมเดลโปรเซสเซอร์ คุณสามารถดูได้ที่imgur.com/a/KP57m6sหรือดูที่แหล่งข่าวโดยตรง
haxpor

คำตอบ:


186

บน Linux (ด้วยเคอร์เนลล่าสุดที่สมเหตุสมผล) คุณสามารถดึงข้อมูลนี้ออกจาก / 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

สิ่งนี้จะให้ข้อมูลเพิ่มเติมเกี่ยวกับแคชจากนั้นคุณก็หวังว่าจะได้รู้รวมถึงขนาด cacheline ( coherency_line_size) รวมถึง CPU ที่แชร์แคชนี้ สิ่งนี้มีประโยชน์มากหากคุณทำการเขียนโปรแกรมแบบมัลติเธรดกับข้อมูลที่ใช้ร่วมกัน (คุณจะได้ผลลัพธ์ที่ดีขึ้นถ้าข้อมูลการแชร์เธรดยังแชร์แคช)


4
ไฟล์ใดบ้างที่มีขนาดสายแคช? ฉันสมมติว่า coherency_line_size หรือ physical_line_partition
paxos1977

27
coherency_line_size
spinfire

6
เพื่อให้แน่ใจว่านี่เป็นไบต์ใช่หรือไม่
Jakub M.

6
ใช่ coherency_line_size มีหน่วยเป็นไบต์
John Zwinck

4
@android: ฉันใช้เครื่อง fedora-18 x64 พร้อมโปรเซสเซอร์ core-i5 cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_sizeส่งคืน64ในระบบของฉัน เช่นเดียวกันสำหรับดัชนี 1,2,3 โฟลเดอร์
Abid Rahman K

141

บน Linux ดูที่ sysconf (3)

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

คุณยังสามารถรับได้จากบรรทัดคำสั่งโดยใช้ getconf:

$ getconf LEVEL1_DCACHE_LINESIZE
64

4
คำตอบง่ายๆเป็นเพียงสิ่งที่ดีที่สุด!
FrankH

3
@warunapww มีหน่วยเป็นไบต์
Maarten Bamelis

ในที่สุด! หวังว่าคนอื่นจะเห็นคำตอบนี้เพื่อประหยัดเวลา
elinx

118

ฉันทำงานกับแคชบรรทัดบางอย่างและต้องการเขียนฟังก์ชันข้ามแพลตฟอร์ม ฉันส่งไปยัง gitub repo ที่https://github.com/NickStrupat/CacheLineSizeหรือคุณสามารถใช้แหล่งข้อมูลด้านล่าง รู้สึกอิสระที่จะทำสิ่งที่คุณต้องการด้วย

#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) สำหรับ linux
Matt

@ แมททำไม? แค่สงสัย :-).
user35915

31

บน x86 คุณสามารถใช้คำสั่งCPUIDกับฟังก์ชัน 2 เพื่อกำหนดคุณสมบัติต่าง ๆ ของแคชและ TLB การแยกเอาท์พุทของฟังก์ชั่น 2 ค่อนข้างซับซ้อนดังนั้นฉันจะดูคุณในส่วน 3.1.3 ของการระบุโปรเซสเซอร์ของIntel และคำสั่ง CPUID (PDF)

ในการรับข้อมูลนี้จากรหัส C / C ++ คุณจะต้องใช้แอสเซมบลีแบบอินไลน์คอมไพเลอร์อินทรินอินหรือเรียกใช้ฟังก์ชันแอสเซมบลีภายนอกเพื่อดำเนินการคำสั่ง CPUID


ใครรู้เกี่ยวกับวิธีการทำเช่นนี้กับโปรเซสเซอร์อื่น ๆ ที่มีแคชในตัว?
paxos1977

3
@ceretullis: เอ่อ ... x86 มีอยู่แล้วในแคช "โปรเซสเซอร์อื่น" คุณกำลังมองหาอะไรโดยเฉพาะ? สิ่งที่คุณขอขึ้นอยู่กับแพลตฟอร์ม
Billy ONeal

9

หากคุณใช้ SDL2 คุณสามารถใช้ฟังก์ชั่นนี้:

int SDL_GetCPUCacheLineSize(void);

ซึ่งส่งคืนขนาดของขนาดบรรทัดแคช L1 เป็นไบต์

ในเครื่อง x86_64 ของฉันให้เรียกใช้ข้อมูลโค้ดนี้:

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

ผลิต CacheLineSize = 64

ฉันรู้ว่าฉันสายไปนิดหน่อย แต่เพียงเพิ่มข้อมูลสำหรับผู้เยี่ยมชมในอนาคต ในปัจจุบันเอกสาร SDL ระบุว่าหมายเลขที่ส่งคืนเป็น KB แต่จริง ๆ แล้วมีหน่วยเป็นไบต์


โอ้นี่มันมีประโยชน์จริงๆ ฉันจะเขียนเกมใน SDL2 ดังนั้นนี่จะเป็นประโยชน์จริง ๆ
Nicholas Humphrey

7

บนแพลตฟอร์ม Windows:

จากhttp://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx

ฟังก์ชัน GetLogicalProcessorInformation จะให้คุณสมบัติของตัวประมวลผลเชิงตรรกะที่ระบบใช้ คุณสามารถเดิน SYSTEM_LOGICAL_PROCESSOR_INFORMATION ที่ส่งคืนโดยฟังก์ชั่นการค้นหารายการประเภท RelationCache แต่ละรายการดังกล่าวประกอบด้วย ProcessorMask ซึ่งจะแจ้งให้คุณทราบว่าตัวประมวลผลรายการใดที่นำไปใช้กับและใน CACHE_DESCRIPTOR รายการนั้นจะบอกคุณว่าประเภทของแคชที่ถูกอธิบายและจำนวนแคชขนาดใหญ่สำหรับแคชนั้น


4

ARMv6 ขึ้นไปมีC0หรือ Cache Type Register อย่างไรก็ตามมันจะใช้ได้เฉพาะในโหมดพิเศษ

ตัวอย่างเช่นจากCortex ™ -A8 คู่มืออ้างอิงทางเทคนิค :

วัตถุประสงค์ของการลงทะเบียนประเภทแคชคือเพื่อกำหนดความยาวบรรทัดต่ำสุดของคำสั่งและแคชข้อมูลเป็นไบต์เพื่อเปิดใช้งานช่วงของที่อยู่ที่ไม่ถูกต้อง

การลงทะเบียนประเภทแคชคือ:

  • การลงทะเบียนแบบอ่านอย่างเดียว
  • สามารถเข้าถึงได้ในโหมดพิเศษเท่านั้น

เนื้อหาของการลงทะเบียนประเภทแคชนั้นขึ้นอยู่กับการใช้งานเฉพาะ รูปที่ 3-2 แสดงการจัดเรียงบิตของการลงทะเบียนประเภทแคช ...


อย่าคิดว่าโปรเซสเซอร์ ARM มีแคช (เห็นได้ชัดว่าบางอย่างสามารถกำหนดค่าได้โดยไม่มี) C0วิธีมาตรฐานในการตรวจสอบก็จะผ่าน จากARM ARMหน้า B6-6:

จาก ARMv6 การลงทะเบียนประเภทแคชของตัวควบคุมระบบร่วมเป็นวิธีที่ได้รับคำสั่งในการกำหนดแคช L1 ดูที่การลงทะเบียนประเภทแคชในหน้า B6-14 นอกจากนี้ยังเป็นวิธีการที่แนะนำสำหรับรุ่นก่อนหน้าของสถาปัตยกรรม นอกจากนี้ข้อควรพิจารณาสำหรับระดับแคชเพิ่มเติมในหน้า B6-12 อธิบายแนวทางสถาปัตยกรรมสำหรับการสนับสนุนแคชระดับ 2


3

นอกจากนี้คุณยังสามารถลองทำแบบโปรแกรมโดยการวัดเวลา เห็นได้ชัดว่ามันไม่แม่นยำเท่าซีพียูและไลค์ แต่มันพกพาได้มากกว่า ATLAS ดำเนินการในขั้นตอนการกำหนดค่าคุณอาจต้องการดู:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.