programing

캐시 라인 크기를 프로그래밍 방식으로 가져오시겠습니까?

goodsources 2022. 8. 30. 22:33
반응형

캐시 라인 크기를 프로그래밍 방식으로 가져오시겠습니까?

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

비슷한 질문:C++의 CPU 캐시 페이지 크기를 프로그래밍 방식으로 가져오려면 어떻게 해야 합니까?

Linux 의 경우는, sysconf(3) 를 참조해 주세요.

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

명령줄에서 getconf를 사용하여 가져올 수도 있습니다.

$ getconf LEVEL1_DCACHE_LINESIZE
64

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를 사용하다이는 공유 데이터를 사용하여 멀티스레드 프로그래밍을 수행하는 경우 매우 유용합니다(데이터를 공유하는 스레드도 캐시를 공유하면 더 나은 결과를 얻을 수 있습니다).

캐시 라인 관련 작업을 하고 있어서 크로스 플랫폼 함수를 작성해야 했습니다.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

C++17 이후 std::hardware_destructive_interference_size를 사용할 수 있습니다.
★★★★

잘못된 공유를 방지하기 위한 두 개체 간의 최소 오프셋입니다.최소 alignof(std::max_align_t)가 보장됩니다.

x86에서는 함수 2와 함께 CPUID 명령을 사용하여 캐시와 TLB의 다양한 속성을 확인할 수 있습니다.함수 2 의 출력의 해석은 다소 복잡하기 때문에, 「Intel Processor Identification and CPUID Instruction (PDF)」의 섹션 3.1.3 을 참조해 주세요.

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

SDL2 를 사용하고 있는 경우는, 다음의 기능을 사용할 수 있습니다.

int SDL_GetCPUCacheLineSize(void);

L1 캐시 행 크기(바이트)를 반환합니다.

x86_64 머신에서 다음 코드 스니펫을 실행하고 있습니다.

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

CacheLineSize = 64

조금 늦은 건 알지만, 앞으로 방문하실 분들을 위해 정보를 추가하려고요.현재 SDL 문서에는 반환된 숫자는 KB로 되어 있지만 실제로는 바이트 단위로 되어 있습니다.

Windows 플랫폼의 경우:

http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx 에서

Get Logical Processor Information 함수는 시스템에서 사용되는 논리 프로세서의 특성을 제공합니다.함수에 의해 반환된SYSTEM_LOGAL_PROCESOR_INFORMATION을 걸어 RelationCache 유형의 엔트리를 검색할 수 있습니다.이러한 각 엔트리에는 해당 엔트리가 적용되는 프로세서를 나타내는 ProcessorMask가 포함되어 있으며, CACHE_DESCRIptOR에서는 어떤 유형의 캐시가 기술되어 있는지 및 해당 캐시의 캐시 행이 얼마나 큰지 알 수 있습니다.

타이밍을 측정하여 프로그래밍 방식으로 실행할 수도 있습니다.물론 cpuid 등처럼 정확하지는 않지만 휴대성은 더 뛰어납니다.ATLAS는 설정 단계에서 이 기능을 수행하므로 다음과 같이 살펴볼 수 있습니다.

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

ARMv6 이상에는 또는 캐시 타입 레지스터가 있습니다.단, 특권 모드에서만 사용할 수 있습니다.

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

캐시 유형 레지스터의 목적은 명령 및 데이터 캐시의 최소 행 길이를 바이트 단위로 결정하고 주소 범위를 비활성화하는 것입니다.

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

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

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


ARM 프로세서에 캐시가 있다고 가정하지 마십시오(일부는 캐시가 없어도 구성할 수 있습니다).이를 판별하는 표준 방법은 를 사용하는 것입니다.ARM에서 B6-6페이지:

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

언급URL : https://stackoverflow.com/questions/794632/programmatically-get-the-cache-line-size

반응형