캐시 라인 크기를 프로그래밍 방식으로 가져오시겠습니까?
모든 플랫폼을 환영합니다. 답변할 플랫폼을 지정하십시오.
비슷한 질문: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
'programing' 카테고리의 다른 글
VueJS - 로컬 json 파일에서 vis.js 타임라인으로 데이터 읽기 (0) | 2022.08.30 |
---|---|
C 프로그램을 여러 파일로 분할하려면 어떻게 해야 합니까? (0) | 2022.08.30 |
상태 변경 시 Vuex getter가 업데이트되지 않음 (0) | 2022.08.30 |
디렉토리를 소스 트리에서 바이너리 트리로 복사하는 방법 (0) | 2022.08.30 |
C 포인터를 NULL로 초기화할 수 있습니까? (0) | 2022.08.30 |