2014-04-07 11 views
10

Gần đây Herb Sutter đã có một cuộc trò chuyện tuyệt vời trên "Modern C++: What You Need to Know". Chủ đề chính của bài nói chuyện này là hiệu quả và cách địa phương dữ liệu và truy cập vào các vấn đề bộ nhớ. Ông cũng đã giải thích cách truy cập tuyến tính của bộ nhớ (mảng/vector) sẽ được yêu thích bởi CPU. Ông đã lấy một ví dụ từ một tài liệu tham khảo cổ điển khác "Game performance by Bob Nystrom" về chủ đề này.Cách viết chương trình thân thiện với bộ nhớ cache trong C++?

Sau khi đọc những bài viết này, tôi đã nhận rằng có hai loại bộ nhớ cache mà tác động việc thực hiện chương trình:

  1. dữ liệu bộ nhớ cache
  2. Hướng dẫn cache

Cachegrind công cụ cũng đo cả hai loại bộ nhớ cache thông tin thiết bị của chương trình của chúng tôi. Những điểm đầu tiên đã được giải thích bởi nhiều bài báo/blog và cách để đạt được hiệu quả bộ nhớ cache dữ liệu tốt (địa phương dữ liệu).

Tuy nhiên tôi không nhận được nhiều thông tin về chủ đề Bộ nhớ cache hướng dẫn và loại điều chúng tôi cần lưu ý trong chương trình để đạt được hiệu suất tốt hơn ?. Theo sự hiểu biết của tôi, chúng tôi (lập trình viên) không có nhiều quyền kiểm soát đối với hướng dẫn nào hoặc thứ tự sẽ thực hiện. Nó sẽ thực sự tốt đẹp nếu các chương trình C++ nhỏ giải thích cách truy cập này (bộ nhớ cache lệnh .i.e) sẽ thay đổi theo kiểu viết chương trình của chúng ta. Các lập trình viên thực hành tốt nhất nên làm theo để đạt được hiệu suất tốt hơn đối với điểm này là gì?

Tôi có nghĩa là chúng ta có thể hiểu về các chủ đề bộ nhớ cache dữ liệu nếu chương trình của chúng tôi thực hiện (vectơ vs danh sách) theo cách tương tự để giải thích về điểm thứ 2. Mục đích chính của câu hỏi này là hiểu chủ đề này càng nhiều càng tốt.

+1

Tránh các chức năng ảo và ngắt mã phức tạp thành các vòng nhỏ hơn. – lpapp

+1

@Leeor: theo cách nào trùng lặp? – lpapp

+0

Xin lỗi, tôi đã đề cập đến câu hỏi sai, tôi sẽ rút lại phiếu bầu khi tôi ở bên cạnh máy tính, nhưng tôi cho rằng nó đã được trả lời trước với mã lưu trữ bối cảnh, bao gồm bộ nhớ cache, bộ nhớ cache đã giải mã, v.v. – Leeor

Trả lời

8

Bất kỳ mã nào thay đổi luồng thực thi sẽ ảnh hưởng đến Bộ nhớ cache hướng dẫn. Điều này bao gồm các cuộc gọi hàm và vòng lặp cũng như các con trỏ hàm dereferencing.

Khi lệnh rẽ nhánh hoặc lệnh nhảy được thực hiện, bộ xử lý phải dành thêm thời gian để quyết định xem mã đã có trong bộ nhớ cache lệnh hay không cần tải lại bộ nhớ cache lệnh (từ đích của nhánh).

Ví dụ: một số bộ xử lý có thể có bộ nhớ cache đủ lớn để giữ mã thực thi cho các vòng nhỏ. Một số bộ xử lý không có bộ nhớ cache lớn và tải lại đơn giản. Việc tải lại bộ nhớ cache của lệnh cần có thời gian để thực hiện các hướng dẫn thực hiện.

Tìm kiếm các chủ đề này:

  • Vòng unrolling
  • thực hiện chỉ thị có điều kiện (có sẵn trên bộ vi xử lý ARM)
  • chức năng Inline
  • đường ống dẫn Hướng dẫn

Sửa 1: Lập trình kỹ thuật để có hiệu suất tốt hơn
Để cải thiện hiệu suất và giảm quá trình tải hướng dẫn bộ nhớ cache làm như sau:

Giảm "nếu" phát biểu Thiết kế mã của bạn để hạn chế tối đa "nếu" phát biểu. Điều này có thể bao gồm Đại số Boolean, sử dụng nhiều phép so sánh toán học hoặc đơn giản hóa hơn (chúng có thực sự cần thiết không?). Ưu tiên giảm nội dung của các mệnh đề "sau đó" và "khác" để trình biên dịch có thể sử dụng các hướng dẫn ngôn ngữ lắp ráp có điều kiện.

Xác định chức năng nhỏ như inline hoặc macro
Có một chi phí gắn liền với chức năng gọi điện thoại, chẳng hạn như lưu trữ vị trí trở lại và nạp lại bộ nhớ cache hướng dẫn. Đối với các hàm có một số lượng nhỏ các câu lệnh, hãy thử đề xuất với trình biên dịch rằng chúng được tạo nội dòng. Nội tuyến có nghĩa là dán nội dung của mã nơi thực thi, thay vì thực hiện cuộc gọi hàm. Kể từ khi cuộc gọi chức năng được tránh, do đó, là cần phải tải lại bộ nhớ cache hướng dẫn.

cuộn vòng
Đối lặp nhỏ, không vòng lặp, nhưng lặp lại nội dung của các vòng lặp (một số trình biên dịch có thể làm được điều này ở các cài đặt mức độ tối ưu hóa cao hơn). Càng nhiều nội dung lặp đi lặp lại, số nhánh ít hơn vào đầu vòng lặp và ít cần phải tải lại bộ nhớ cache lệnh.

Sử dụng bảng tra cứu, không phải "nếu" phát biểu
Một số chương trình sử dụng "if-else-if" thang cho dữ liệu bản đồ cho các giá trị. Mỗi câu lệnh "if" là ngắt trong thực thi trong bộ nhớ cache lệnh. Đôi khi, với một toán nhỏ, các giá trị có thể được đặt trong một bảng như một mảng và chỉ số được tính toán. Khi chỉ mục được biết, bộ xử lý có thể truy xuất dữ liệu mà không làm gián đoạn bộ nhớ cache lệnh.

Thay đổi dữ liệu hoặc dữ liệu cấu trúc
Nếu kiểu dữ liệu là hằng số, một chương trình có thể được tối ưu hóa trên các dữ liệu. Ví dụ, một chương trình xử lý các gói tin có thể căn cứ vào các hoạt động của nó dựa trên các ID gói (suy nghĩ mảng các con trỏ hàm). Chức năng sẽ được tối ưu hóa để xử lý gói.

Thay đổi danh sách được liên kết thành mảng hoặc vùng chứa truy cập ngẫu nhiên khác. Các phần tử của một mảng có thể được truy cập bằng cách sử dụng toán học và không thực hiện ngắt. Danh sách được liên kết phải được duyệt qua (vòng lặp) để tìm một mục.

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