2012-04-25 44 views
6

Tôi hiểu phần đệm diễn ra giữa các thành viên của cấu trúc để đảm bảo căn chỉnh các loại riêng lẻ. Tuy nhiên, tại sao cấu trúc dữ liệu phải là một bội số của sự liên kết của thành viên lớn nhất? Tôi không hiểu phần đệm là cần thiết ở cuối.tại sao kích thước của cấu trúc cần phải là bội số của sự liên kết lớn nhất của bất kỳ cấu trúc nào

tham khảo: http://en.wikipedia.org/wiki/Data_structure_alignment

Trả lời

7

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ọ.

+1

* 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. –

+1

@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. –

+1

@ 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. –

0

Bởi vì giải quyết ảo.

"... sắp xếp một trang trên một ranh giới trang có kích thước cho phép bản đồ phần cứng một địa chỉ ảo đến một địa chỉ vật lý bằng cách thay các bit cao trong địa chỉ, chứ không phải là làm số học phức tạp."

Nhân tiện, tôi đã tìm thấy trang Wikipedia về điều này được viết khá tốt.

+1

Không liên quan .... –

0

Nếu kích thước đăng ký của CPU là 32 bit, thì nó có thể lấy bộ nhớ trên ranh giới 32 bit với một lệnh lắp ráp đơn. Nó là chậm hơn để lấy 32 bit, và sau đó nhận được byte bắt đầu tại bit 8.

BTW: Không cần phải đệm. Bạn có thể yêu cầu các cấu trúc đó được đóng gói.

+1

Đóng gói là trình biên dịch cụ thể, không phải bằng ngôn ngữ. Việc đóng gói sẽ nổ tung trên các máy RISC, nếu hỗ trợ CPU/hạt nhân để xử lý các tải trọng và cửa hàng không được điều chỉnh không có hoặc không được bật. Căn chỉnh chỉ cho tốc độ; đó là một yêu cầu khó khăn trên một số máy. – Kaz

1

Tùy thuộc vào phần cứng, việc căn chỉnh có thể cần thiết hoặc chỉ giúp tăng tốc quá trình thực thi.

Có một số bộ vi xử lý nhất định (ARM tôi tin) trong đó quyền truy cập chưa được ký dẫn đến ngoại lệ phần cứng. Đơn giản và đơn giản. Mặc dù các bộ vi xử lý x86 điển hình hơn, nhưng vẫn có một hình phạt khi truy cập các kiểu cơ bản không được ký hiệu, vì bộ vi xử lý phải làm nhiều việc hơn để đưa các bit vào thanh ghi trước khi có thể hoạt động trên đó. Các trình biên dịch thường cung cấp các thuộc tính/pragmas cụ thể khi vẫn cần đóng gói.

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