프로그래밍 방식으로 캐시 라인 크기를 얻습니까?


177

모든 플랫폼을 환영합니다. 답을위한 플랫폼을 지정하십시오.

비슷한 질문 : 프로그래밍 방식으로 C ++에서 CPU 캐시 페이지 크기를 얻는 방법은 무엇입니까?


8
: FWIW는 C ++ 17이의 컴파일 시간 근사 제공합니다 stackoverflow.com/questions/39680206/...
GManNickG

C / C ++을 제외하고 어셈블리를 사용하여 그러한 정보를 얻는 것이 마음에 들지 않으면 SDL2의 소스 코드 SDL_GetCPUCacheLineSize기능을 살펴보고 (negamartin의 답변에서 정보를 확장) cpuid macro각 소스 코드가있는 어셈블리 코드를 살펴보십시오 프로세서 모델 imgur.com/a/KP57m6s 를 보거나 직접 소스를 들여다 볼 수 있습니다 .
haxpor 2019

답변:


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

이것은 캐시 라인 크기 ( coherency_line_size)와이 캐시를 공유하는 CPU를 포함하여 캐시에 대한 자세한 정보를 제공합니다 . 공유 데이터로 다중 스레드 프로그래밍을 수행하는 경우 매우 유용합니다 (데이터를 공유하는 스레드가 캐시를 공유하는 경우 더 나은 결과를 얻을 수 있습니다).


4
어떤 파일이 캐시 라인 크기를 포함합니까? coherency_line_size를 가정하고 있습니까? 또는 physical_line_partition?
paxos1977

27
coherency_line_size
spinfire

6
확실하게 : 이것은 바이트입니다, 예?
Jakub M.

6
예, coherency_line_size는 바이트 단위입니다.
존 즈 빙크

4
@android : core-i5 프로세서와 함께 fedora-18 x64 시스템을 사용합니다. 내 시스템으로 cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_size돌아갑니다 64. index1,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

캐시 라인 관련 작업을하고 있으며 크로스 플랫폼 기능을 작성해야했습니다. https://github.com/NickStrupat/CacheLineSize 에서 github 저장소에 커밋 하거나 아래 소스를 사용할 수 있습니다. 당신이 원하는대로 자유롭게 할 수 있습니다.

#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)를 사용하는 것이 좋습니다.
Matt

@ 매트 왜? 그냥 궁금해서 :-).
user35915

31

x86에서 함수 2와 함께 CPUID 명령어를 사용 하여 캐시 및 TLB의 다양한 속성을 결정할 수 있습니다 . 함수 2의 출력 구문 분석은 다소 복잡하므로 인텔 프로세서 식별 및 CPUID 명령 (PDF)의 3.1.3 절을 참조합니다 .

C / C ++ 코드에서이 데이터를 가져 오려면 인라인 어셈블리, 컴파일러 내장 함수를 사용하거나 외부 어셈블리 함수를 호출하여 CPUID 명령을 수행해야합니다.


캐시가 내장 된 다른 프로세서 로이 작업을 수행하는 방법에 대해 아는 사람이 있습니까?
paxos1977

3
@ceretullis : Errr ... 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 함수는 시스템에서 사용중인 논리 프로세서의 특성을 제공합니다. RelationCache 유형의 항목을 찾는 함수가 리턴 한 SYSTEM_LOGICAL_PROCESSOR_INFORMATION을 진행할 수 있습니다. 이러한 각 항목에는 항목이 적용되는 프로세서를 알려주는 ProcessorMask가 포함되어 있으며, CACHE_DESCRIPTOR에서는 어떤 유형의 캐시가 설명되고 있으며 캐시 라인의 크기가 그 캐시에 얼마나 큰지를 알려줍니다.


4

ARMv6 이상에는 C0캐시 유형 레지스터가 있습니다. 그러나 권한 모드에서만 사용할 수 있습니다.

예를 들어, Cortex ™ -A8 기술 참조 설명서 :

캐시 유형 레지스터의 목적은 주소 범위를 무효화 할 수 있도록 명령 및 데이터 캐시 최소 라인 길이 (바이트)를 결정하는 것입니다.

캐시 유형 레지스터는 다음과 같습니다.

  • 읽기 전용 레지스터
  • 권한 모드에서만 액세스 할 수 있습니다.

캐시 유형 레지스터의 내용은 특정 구현에 따라 다릅니다. 그림 3-2는 캐시 유형 레지스터의 비트 배열을 보여줍니다.


ARM 프로세서에 캐시가 있다고 가정하지 마십시오 (아마도 일부는 캐시없이 구성 할 수 있음). 그것을 결정하는 표준 방법은 C0입니다. 로부터 ARM ARM , 페이지 B6-6 :

ARMv6부터 시스템 제어 보조 프로세서 캐시 유형 레지스터는 L1 캐시를 정의하는 필수 방법입니다 (B6-14 페이지의 캐시 유형 레지스터 참조). 또한 이전 아키텍처 변형에 권장되는 방법입니다. 또한 B6-12 페이지의 추가 수준의 캐시에 대한 고려 사항은 수준 2 캐시 지원에 대한 아키텍처 지침을 설명합니다.


3

타이밍을 측정하여 프로그래밍 방식으로 시도 할 수도 있습니다. 분명히 그것은 cpuid와 같은 것만 큼 정확하지는 않지만 더 휴대하기 쉽습니다. ATLAS는 구성 단계에서 수행하므로 다음을 참조하십시오.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.