Câu hỏi hay. Hãy xem xét loại giả thuyết này:
struct A {
int n;
bool flag;
};
Vì vậy, một đối tượng kiểu A
nên lấy năm byte (bốn cho int cộng một cho bool), nhưng trong thực tế phải mất tám. Tại sao?
Câu trả lời được xem nếu bạn sử dụng các loại như thế này:
const size_t N = 100;
A a[N];
Nếu mỗi A
chỉ lăm byte, sau đó a[0]
sẽ sắp xếp nhưng a[1]
, a[2]
và hầu hết các yếu tố khác thì không.
Nhưng tại sao tính liên kết lại quan trọng? Có nhiều lý do, tất cả liên quan đến phần cứng. Một lý do là bộ nhớ được sử dụng gần đây/thường xuyên được lưu trữ trong các dòng bộ nhớ cache trên CPU CPU để truy cập nhanh. Một đối tượng liên kết nhỏ hơn một dòng bộ nhớ cache luôn luôn phù hợp trong một dòng đơn (nhưng xem các chú thích thú vị được thêm vào bên dưới), nhưng một đối tượng không được ký hiệu có thể nằm giữa hai dòng, làm lãng phí bộ nhớ cache.
Thậm chí còn có nhiều lý do phần cứng cơ bản hơn, phải làm theo cách dữ liệu byte địa chỉ được chuyển xuống một bus dữ liệu 32 hoặc 64 bit, ngoài các dòng bộ nhớ cache. Việc điều chỉnh không chính xác làm tắc nghẽn bus với các lần nạp thêm (do trước đây để sắp xếp), nhưng nó cũng sẽ buộc các thanh ghi chuyển byte khi chúng đi vào. Thậm chí tệ hơn, sự lệch hướng có xu hướng làm rối loạn logic tối ưu hóa (ít nhất là nó có, mặc dù tôi không có kiến thức cá nhân về điểm cuối cùng này). Vì vậy, sự lệch hướng là rất xấu từ quan điểm hiệu suất.
Thường thì đáng để lãng phí byte đệm vì những lý do này.
Cập nhật: Tất cả nhận xét bên dưới đều hữu ích. Tôi đề nghị họ.
* Một đối tượng liên kết nhỏ hơn một dòng bộ nhớ cache luôn luôn phù hợp trong một dòng duy nhất, nhưng một đối tượng không được ký hiệu có thể nằm giữa hai dòng *> ** Không **. Cho dù liên kết hay không một đối tượng có thể nằm giữa hai dòng. –
@MatthieuM., Thực sự là có và không. Kích thước dòng bộ nhớ cache là bội số của kích thước dữ liệu lớn nhất và bất kỳ loại cơ bản nào khác. Do đó, tất cả các loại _native_ liên kết (er, hầu hết) sẽ tự nhiên nằm trong một dòng bộ nhớ cache duy nhất. Hãy xem xét rằng bất kỳ loại liên kết 1,2,4,8,16 byte nào sẽ được căn chỉnh tự động để vừa với một dòng bộ nhớ cache 64 hoặc 128 byte. Một hệ thống về cơ bản sẽ không sử dụng được nếu đây không phải là trường hợp. –
@ edA-qamort-ora-y: chắc chắn, nhưng một đối tượng là một hợp chất của các loại cơ bản có thể dễ dàng nằm giữa hai dòng. Ngay cả khi nó nhỏ hơn. Giả sử một dòng 64 byte, tôi có thể có một đối tượng lớn 48 byte, và trong một bảng các đối tượng như vậy, ít nhất một trong hai đối tượng sẽ nằm giữa hai dòng bộ nhớ cache. –