2009-04-27 37 views
142

Mọi nền tảng đều được chào đón, vui lòng chỉ định nền tảng cho câu trả lời của bạn.Lập trình có kích thước dòng bộ nhớ cache?

Một câu hỏi tương tự: How to programmatically get the CPU cache page size in C++?

+5

FWIW, C++ 17 sẽ cung cấp một xấp xỉ biên dịch thời gian này: http://stackoverflow.com/questions/39680206/understanding-stdhardware-destructive-interference-size-and-stdhardware-cons – GManNickG

Trả lời

29

Trên x86, bạn có thể sử dụng các hướng dẫn CPUID với chức năng 2 để xác định thuộc tính khác nhau của bộ nhớ cache và các TLB. Phân tích cú pháp đầu ra của hàm số 2 có phần phức tạp, vì vậy tôi sẽ giới thiệu bạn đến phần 3.1.3 của Intel Processor Identification and the CPUID Instruction (PDF).

Để lấy dữ liệu này từ mã C/C++, bạn sẽ cần sử dụng lắp ráp nội tuyến, nội tại trình biên dịch hoặc gọi hàm lắp ráp bên ngoài để thực hiện lệnh CPUID.

+0

bất kỳ ai biết về làm thế nào để làm điều này với các bộ vi xử lý khác với bộ nhớ đệm tích hợp? – paxos1977

+2

@ceretullis: Errr ... x86 đã được xây dựng trong bộ nhớ cache. Những gì "bộ vi xử lý khác" là bạn đặc biệt tìm kiếm?Những gì bạn đang yêu cầu là nền tảng phụ thuộc. –

2

Bạn cũng có thể thử làm theo cách lập trình bằng cách đo thời gian. Rõ ràng, nó sẽ không phải lúc nào cũng chính xác như cpuid và thích, nhưng nó là xách tay hơn. ATLAS làm nó ở giai đoạn cấu hình của nó, bạn có thể muốn nhìn vào nó:

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

143

Trên Linux (với một hạt nhân gần đây một cách hợp lý), bạn có thể nhận được thông tin này ra khỏi/sys:

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

Thư mục này có thư mục phụ cho từng cấp bộ nhớ cache. Mỗi thư mục chứa các tệp sau:

coherency_line_size 
level 
number_of_sets 
physical_line_partition 
shared_cpu_list 
shared_cpu_map 
size 
type 
ways_of_associativity 

Điều này cung cấp cho bạn thêm thông tin về bộ nhớ cache mà bạn từng biết, bao gồm kích thước bộ nhớ cache cũng như những gì CPU chia sẻ bộ nhớ cache này. Điều này rất hữu ích nếu bạn đang thực hiện lập trình đa luồng với dữ liệu được chia sẻ (bạn sẽ nhận được kết quả tốt hơn nếu các chủ đề chia sẻ dữ liệu cũng đang chia sẻ bộ đệm).

+4

tệp nào chứa kích thước dòng bộ nhớ cache? Tôi giả định coherency_line_size? hoặc physical_line_partition? – paxos1977

+19

coherency_line_size – spinfire

+5

Để chắc chắn: đây là trong Bytes, có? –

6

Trên nền tảng Windows:

từ http://blogs.msdn.com/oldnewthing/archive/2009/12/08/9933836.aspx

Chức năng GetLogicalProcessorInformation sẽ cung cấp cho bạn đặc của bộ xử lý logic được sử dụng bởi hệ thống. Bạn có thể đi bộ SYSTEM_LOGICAL_PROCESSOR_INFORMATION được trả lại bằng chức năng tìm kiếm các mục nhập loại RelationCache. Mỗi entry như vậy chứa một ProcessorMask mà cho bạn biết xử lý (s) mục áp dụng cho, và trong CACHE_DESCRIPTOR, nó cho bạn biết những gì loại bộ nhớ cache đã được mô tả và lớn như thế nào dòng bộ nhớ cache là dành cho rằng bộ nhớ cache.

104

Trên Linux xem sysconf (3).

sysconf (_SC_LEVEL1_DCACHE_LINESIZE) 

Bạn cũng có thể lấy nó từ dòng lệnh sử dụng getconf:

$ getconf LEVEL1_DCACHE_LINESIZE 
64 
+3

câu trả lời đơn giản chỉ là tốt nhất! –

+0

đơn vị là gì? bit hoặc byte? – warunapww

+1

@warunapww Nó bằng byte. –

100

Tôi đã được làm việc trên một số công cụ dòng bộ nhớ cache và cần thiết để viết một hàm cross-platform. Tôi cam kết với một repo github tại https://github.com/NickStrupat/CacheLineSize hoặc bạn chỉ có thể sử dụng nguồn bên dưới. Hãy làm bất cứ điều gì bạn muốn với nó.

#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 
+11

Có thể tốt hơn khi sử dụng sysconf (_SC_LEVEL1_DCACHE_LINESIZE) cho Linux. – Matt

4

ARMv6 trở lên có C0 hoặc Cache Loại Đăng ký. Tuy nhiên, nó chỉ có sẵn trong chế độ đặc quyền.

Ví dụ, từ Cortex™-A8 Technical Reference Manual:

Mục đích của Cache Loại ký là để xác định độ dài hướng dẫn và bộ nhớ cache dữ liệu dòng tối thiểu tính bằng byte để cho phép một loạt các địa chỉ để không còn giá trị.

Cache Loại ký là:

  • một chỉ đọc đăng ký
  • truy cập chỉ trong chế độ đặc quyền.

Nội dung của Sổ đăng ký loại bộ nhớ cache phụ thuộc vào việc thực hiện cụ thể. Hình 3-2 cho thấy sự sắp xếp chút Cache Loại Register ...


Đừng cho rằng bộ vi xử lý ARM có một bộ nhớ cache (rõ ràng, một số có thể được cấu hình nếu không có). Cách tiêu chuẩn để xác định nó là qua C0. Từ B6-6 ARM ARM, trang:

từ ARMv6, Type đăng ký Hệ thống kiểm soát coprocessor Cache là các phương pháp bắt buộc để xác định các cache L1, xem bộ nhớ cache Loại đăng ký trên trang B6-14. Đây cũng là phương pháp được đề xuất cho các biến thể cũ của kiến ​​trúc . Ngoài ra, các cân nhắc về các mức bổ sung là bộ nhớ cache trên trang B6-12 mô tả các nguyên tắc về kiến ​​trúc cho mức hỗ trợ bộ nhớ cache cấp 2 .

5

Nếu bạn đang sử dụng SDL2 bạn có thể sử dụng chức năng này:

int SDL_GetCPUCacheLineSize(void); 

nào trả về kích thước của kích thước L1 dòng bộ nhớ cache, tính bằng byte.

Trong máy x86_64 của tôi, chạy đoạn mã này:

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

Tạo CacheLineSize = 64

Tôi biết tôi là một chút muộn, nhưng chỉ cần thêm thông tin cho du khách trong tương lai. Tài liệu SDL hiện cho biết số được trả về bằng KB, nhưng thực tế là theo byte.

+0

Ồ, điều này thực sự hữu ích. Tôi sẽ viết một số trò chơi trong SDL2 để điều này thực sự hữu ích –

Các vấn đề liên quan