Lập trình có được kích thước dòng bộ đệm?


177

Tất cả các 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.

Một câu hỏi tương tự: Làm thế nào để lập trình có được kích thước trang bộ đệm CPU trong C ++?


8
FWIW, C ++ 17 sẽ cung cấp xấp xỉ thời gian biên dịch cho điều này: stackoverflow.com/questions/39480206/iêu
GManNickG

dành cho C / C ++, nếu bạn không phiền khi sử dụng lắp ráp để có được thông tin đó, bạn có thể xem (mở rộng thông tin từ câu trả lời của negamartin) tại mã nguồn của SDL_GetCPUCacheLineSizehàm SDL2 , sau đó hãy xem cpuid macromã nguồn nào có mã nguồn lắp ráp cho mỗi của mô hình bộ xử lý. Bạn có thể xem imgur.com/a/KP57m6s hoặc trực tiếp nhìn vào nguồn.
haxpor

Câu trả lời:


186

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

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

Thư mục này có một thư mục con cho mỗi cấp độ của bộ đệm. 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ộ đệm mà bạn hy vọng sẽ biết, bao gồm kích thước bộ đệm ( coherency_line_size) cũng như CPU ​​chia sẻ bộ đệm 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 luồng chia sẻ dữ liệu cũng đang chia sẻ bộ đệm).


4
tập tin nào chứa kích thước dòng bộ đệm? Tôi đang giả sử coherency_line_size? hoặc vật lý_line_partition?
paxos1977

27
coherency_line_size
spinfire

6
Để chắc chắn: đây là bằng Byte, vâng?
Jakub M.

6
Có, coherency_line_size tính bằng byte.
John Zwinck

4
@android: Tôi sử dụng máy fedora-18 x64 với bộ xử lý core-i5. cat /sys/devices/system/cpu/cpu0/cache/index0/coherency_line_sizetrả về 64trong hệ thống của tôi Tương tự cho các thư mục index1,2,3.
Abid Rahman K

141

Trên Linux, hãy nhìn vào sysconf (3).

sysconf (_SC_LEVEL1_DCACHE_LINESIZE)

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

$ getconf LEVEL1_DCACHE_LINESIZE
64

4
câu trả lời đơn giản là tốt nhất!
FrankH.

3
@warunapww Nó tính bằng byte.
Maarten Bamelis

cuối cùng hy vọng nhiều người nhìn thấy câu trả lời này để tiết kiệm thời gian.
elinx

118

Tôi đã làm việc trên một số công cụ dòng bộ đệm và cần thiết để viết một chức năng đa nền tảng. Tôi đã cam kết nó 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 dưới đây. 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

15
Có thể tốt hơn để sử dụng sysconf (_SC_LEVEL1_DCACHE_LINESIZE) cho linux.
Matt

@Matt tại sao? Chỉ tò mò :-).
dùng35915

31

Trên x86, bạn có thể sử dụng lệnh CPUID với chức năng 2 để xác định các thuộc tính khác nhau của bộ đệm và TLB. Phân tích cú pháp đầu ra của chức năng 2 hơi phức tạp, vì vậy tôi sẽ giới thiệu cho bạn phần 3.1.3 của Nhận dạng Bộ xử lý Intel và Hướng dẫn CPUID (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 của trình biên dịch hoặc gọi một hàm lắp ráp bên ngoài để thực hiện lệnh CPUID.


Bất cứ ai biết về cách làm điều này với các bộ xử lý khác có bộ nhớ cache tích hợp?
paxos1977

3
@ceretullis: Errr ... x86 đã được tích hợp sẵn trong bộ đệm. "Bộ xử lý khác" mà bạn đang tìm kiếm cụ thể là gì? Những gì bạn đang yêu cầu là phụ thuộc vào nền tảng.
Billy ONeal

9

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);

Trả về kích thước của kích thước dòng bộ đệm L1, 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());

Sản xuất CacheLineSize = 64

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


Oh của tôi điều này thực sự hữu ích. Tôi sẽ viết một số trò chơi trong SDL2 vì vậy điều này sẽ thực sự hữu ích
Nicholas Humphrey

7

Trên nền tảng Windows:

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

Hàm GetLogicalProcessorIn information sẽ cung cấp cho bạn các đặc điểm của bộ xử lý logic được sử dụng bởi hệ thống. Bạn có thể đi bộ HỆ THỐNG_LOGICS_PROCESSOR_INFORMATION được trả về bởi hàm tìm kiếm các mục thuộc loại RelationCache. Mỗi mục như vậy chứa một ProcessorMask cho bạn biết (các) bộ xử lý nào được áp dụng cho, và trong CACHE_DESCRIPTOR, nó sẽ cho bạn biết loại bộ đệm nào được mô tả và dòng bộ đệm cho bộ đệm đó lớn như thế nào.


4

ARMv6 trở lên có C0hoặc Đăng ký loại bộ đệm. Tuy nhiên, nó chỉ có sẵn trong chế độ đặc quyền.

Ví dụ: từ Hướng dẫn tham khảo kỹ thuật Cortex ™ -A8 :

Mục đích của Thanh ghi loại bộ đệm là để xác định hướng dẫn và độ dài dòng tối thiểu của bộ đệm dữ liệu theo byte để cho phép một phạm vi địa chỉ bị vô hiệu.

Đăng ký loại bộ đệm là:

  • đăng ký chỉ đọc
  • chỉ có thể truy cập trong các chế độ đặc quyền.

Nội dung của Đăng ký loại bộ đệm phụ thuộc vào việc triển khai cụ thể. Hình 3-2 cho thấy sự sắp xếp bit của Thanh ghi loại bộ đệm ...


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

Từ ARMv6, thanh ghi Loại bộ đệm Bộ điều khiển hệ thống điều khiển hệ thống là phương thức bắt buộc để xác định bộ đệm L1, xem thanh ghi Loại bộ đệm trên trang B6-14. Nó cũng là phương pháp được đề xuất cho các biến thể trước đó của kiến ​​trúc. Ngoài ra, Cân nhắc về các mức bộ đệm bổ sung trên trang B6-12 mô tả các nguyên tắc kiến ​​trúc để hỗ trợ bộ đệm cấp 2.


3

Bạn cũng có thể thử làm nó bằng lập trình bằng cách đo thời gian. Rõ ràng, nó sẽ không luôn chính xác như cpuid và lượt thích, nhưng nó dễ mang theo hơn. ATLAS thực hiện nó ở giai đoạn cấu hình của nó, bạn có thể muốn xem xét nó:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.