2010-09-29 27 views
14

Thứ tự của các thành viên trong kiến ​​trúc nhị phân của các đối tượng của một lớp bằng cách nào đó có tác động đến hiệu năng của các ứng dụng sử dụng lớp đó? và tôi tự hỏi làm thế nào để quyết định thứ tự các thành viên của POD trong trường hợp câu trả lời là có bởi vì lập trình viên xác định thứ tự của các thành viên thông qua thứ tự của các tuyên bố của họThứ tự của các thành viên của các đối tượng trong lớp có ảnh hưởng gì đến hiệu suất không?

Trả lời

28

Tuyệt đối. C++ đảm bảo rằng thứ tự của các đối tượng trong bộ nhớ giống như thứ tự khai báo, trừ khi bộ định danh truy cập can thiệp.

Đối tượng nằm liền kề có nhiều khả năng nằm trên cùng một đường dẫn, do đó, một truy cập bộ nhớ sẽ tìm nạp cả hai (hoặc xóa cả hai từ bộ nhớ cache). Hiệu quả bộ nhớ cache cũng có thể được cải thiện vì tỷ lệ dữ liệu hữu ích bên trong nó có thể cao hơn. Nói một cách đơn giản, địa phương không gian trong mã của bạn dịch sang địa phương không gian để thực hiện.

Ngoài ra, như Jerry ghi chú trong các nhận xét, thứ tự có thể ảnh hưởng đến lượng đệm. Sắp xếp các thành viên bằng cách giảm kích thước, cũng bằng cách giảm sự liên kết (thường xử lý một mảng chỉ là một phần tử thuộc loại của nó và thành viên cấu trúc là thành viên được căn chỉnh nhất của nó). Đệm không cần thiết có thể làm tăng tổng kích thước của cấu trúc, dẫn đến lưu lượng bộ nhớ cao hơn.

C++ 03 §9/12:

dữ liệu không tĩnh thành viên của một (phi đoàn) lớp tuyên bố mà không có một can thiệp access-specifier được phân bổ để các thành viên sau có địa chỉ cao hơn trong một đối tượng lớp . Thứ tự phân bổ thành viên dữ liệu phi tĩnh được ngăn cách bởi một số truy cập-specifier không được chỉ định (11.1). Yêu cầu thực hiện các yêu cầu có thể khiến hai thành viên liền kề không được phân bổ ngay sau mỗi khác; có thể yêu cầu không gian để quản lý các chức năng ảo (10.3) và các lớp cơ sở ảo (10.1).

+2

Ồ, tôi không nhận ra nhưng tôi đã đăng câu trả lời này 112 * giây * sau khi câu hỏi được đăng! – Potatoswatter

+0

@Potatoswatter_cool thành tích !!! – Pooria

+0

Ngoài ra kích thước của nó cũng quan trọng. Vì bộ xử lý x86 (và có lẽ nhiều bộ xử lý khác) có các opcodes đặc biệt để truy cập bộ nhớ với thanh ghi chỉ mục, một mảng các đối tượng có kích thước 1, 2, 4 hoặc 8 byte sẽ được truy cập nhanh hơn. – ruslik

7

Hoàn toàn đồng ý với Potatoswatter. Tuy nhiên, cần thêm một điểm nữa về các dòng bộ nhớ cache CPU.

Nếu ứng dụng của bạn đa luồng và các chủ đề khác đọc/ghi các cấu trúc của bạn - điều quan trọng là đảm bảo các thành viên đó là không phải trong cùng một dòng bộ nhớ cache.

Vấn đề là bất cứ khi nào một luồng sửa đổi địa chỉ bộ nhớ được lưu trong bộ nhớ cache trong CPU khác - CPU đó sẽ vô hiệu hóa ngay lập tức dòng bộ nhớ cache chứa địa chỉ đó. Vì vậy, thứ tự thành viên không đúng có thể dẫn đến việc vô hiệu hóa bộ đệm không hợp lệ và suy giảm hiệu suất.

4

Ngoài việc thực hiện runtime, được mô tả trong các câu trả lời bộ nhớ cache-line liên quan, tôi nghĩ rằng người ta cũng nên xem xét hiệu suất bộ nhớ, ví dụ: kích thước của đối tượng lớp.

Do số padding, kích thước của đối tượng lớp phụ thuộc vào thứ tự khai báo biến thành viên.

Việc kê khai sau có lẽ sẽ mất 12 byte

class foo { 
    char c1; 
    int i; 
    char c2; 
} 

Tuy nhiên, khi đơn giản lại trật tự của lệnh khai báo thành viên, sau đây có lẽ sẽ mất 8 byte

class bar { 
    int i; 
    char c1; 
    char c2; 
} 

Trong máy thẳng hàng với các từ 4 byte:

sizeof(foo) = 12 

nhưng

sizeof(bar) = 8 
Các vấn đề liên quan