2015-07-06 18 views
5

Vì vậy, tôi đọc rằng khi các biến được khai báo trong C++ nếu bạn muốn có bộ nhớ cache tối ưu, bộ nhớ sẽ được gắn vào căn chỉnh tự nhiên của nó. Ví dụ:Liên kết bộ nhớ C++

int a; // memory address should end in 0x0,0x4,0x8,0xC 
int b[2]; // 8 bytes 0x0,0x8 
int b[4]; // 16 bytes 0x0 

Nhưng trong thực tế, các biến này không tuân theo quy tắc "căn chỉnh tự nhiên", biến 16 byte đang nằm tại địa chỉ bộ nhớ kết thúc bằng 0xC. Tại sao điều này?

+3

Mảng không quan tâm đến bởi sự liên kết, chỉ có các yếu tố cá nhân là – Quentin

+0

Có thể muốn trang web trường hợp chính xác –

+0

Không có trường hợp thực sự im chỉ là thử nghiệm, tất cả tôi có thể tìm thấy được rằng bất kể kích thước biến tất cả nó luôn 4 byte được căn chỉnh trừ khi nó là một kiểu dữ liệu 1 byte. Chỉ cần tò mò tại sao. – Student123

Trả lời

4

Liên kết bộ nhớ tự nhiên thường đề cập đến căn chỉnh của các biến riêng lẻ, không phải là mảng của các biến. Vì vậy, một mảng các số nguyên 4 byte (như bạn dường như có ở trên) được liên kết tự nhiên với một ranh giới 4 byte và không đến ranh giới 16 byte.

chỉnh bộ nhớ tự nhiên thường gắn liền với cách hướng dẫn tải/cửa hàng của CPU được kiến ​​trúc và thực hiện, không phải là kích thước của dòng bộ nhớ cache. CPU không nạp toàn bộ mảng tại một thời điểm (ngoại trừ tải vectơ). Vì vậy, CPU không thực sự quan tâm nếu một số nguyên nó đang tải là một phần của mảng hay không.

Vector tải, mà làm load mảng nhỏ cùng một lúc, thường có các yêu cầu liên kết chặt chẽ hơn. Ví dụ: để thực hiện tải vectơ liên kết trên x86, mục phải được căn chỉnh thành 16 byte.

+0

Tôi cũng thử với 16 kiểu byte byte dữ liệu vẫn chưa được căn chỉnh với 0x0. Tất cả tôi có thể nói là tất cả mọi thứ là 4 byte liên kết bất kể kích thước. Một số trình biên dịch có thực hiện điều này một cách khác biệt hoặc các CPU khác nhau không? – Student123

1

Không đảm bảo liên kết

+0

Phải là một bình luận. – scohe001

+1

@LegalizeNó là câu trả lời đầy đủ, OP tuyên bố rằng liên kết nên là một cái gì đó, tôi đã nói không có người bảo lãnh. Phần còn lại của câu trả lời được đưa ra trong bình luận thứ nhất. Một int có thể có một địa chỉ là lẻ, nó có khả năng sẽ không, nhưng nó có thể. –

+0

@ scohe001 mình một câu trả lời –

2

C++ sẽ không căn chỉnh bất kỳ thứ gì trên dòng bộ nhớ cache vì tất cả ý định và mục đích không biết có bộ nhớ cache.

Nếu bạn muốn nội dung nào đó được căn chỉnh trên ranh giới 16 byte hãy thử posix_memalign() cho những thứ trên heap hoặc (nếu sử dụng GCC) trên ngăn xếp, int x __attribute__ ((aligned (16))). Trong C++ 11 có alignas specifier.

Tôi không biết một cách để gọi new() với một liên kết đảm bảo mặc dù.

+0

Bạn có thể viết 'điều hành của riêng bạn mới() 'và thực thi kết –

+0

Tôi đúng khi nói rằng cùng là một đoạn bộ nhớ là liên kết 4 byte CPU sẽ luôn luôn tận dụng tối đa của dữ liệu và sẽ không phải làm nhiều hơn một lần đọc để nhận được bất kỳ biến 4 byte nào? – Student123

+0

@ Student123 Tôi đoán điều này sẽ phụ thuộc vào CPU. Tôi sẽ nói rằng nói chung đó là một nguyên tắc tốt để làm theo. Tôi biết các kiến ​​trúc vi x86 hiện đại không phạt các lần tải không được ký hiệu nữa. – hayesti

0

Theo Intel® 64 và IA-32 Kiến trúc Optimization Reference Manual (phần B.4.5.2 Giúp),

32-byte lệnh AVX cửa hàng mà span hai trang yêu cầu hỗ trợ với chi phí khoảng 150 chu kỳ.