Hàng rào ký ức là gì?


Câu trả lời:


115

Để tăng hiệu suất, các CPU hiện đại thường thực hiện các lệnh không theo thứ tự để sử dụng tối đa silicon có sẵn (bao gồm cả đọc / ghi bộ nhớ). Bởi vì phần cứng thực thi tính toàn vẹn của hướng dẫn nên bạn không bao giờ nhận thấy điều này trong một chuỗi thực thi. Tuy nhiên, đối với nhiều luồng hoặc môi trường có bộ nhớ dễ bay hơi (ví dụ I / O được ánh xạ bộ nhớ), điều này có thể dẫn đến hành vi không thể đoán trước.

Hàng rào / hàng rào bộ nhớ là một lớp hướng dẫn có nghĩa là việc đọc / ghi bộ nhớ diễn ra theo thứ tự bạn mong đợi. Ví dụ: 'hàng rào đầy đủ' có nghĩa là tất cả các lần đọc / ghi trước hàng rào được bắt đầu trước những lần đọc / ghi sau hàng rào.

Lưu ý hàng rào bộ nhớ là một khái niệm phần cứng. Trong các ngôn ngữ cấp cao hơn, chúng ta đã quen với việc xử lý mutexes và semaphores - những ngôn ngữ này có thể được triển khai bằng cách sử dụng hàng rào bộ nhớ ở cấp độ thấp và việc sử dụng rõ ràng các hàng rào bộ nhớ là không cần thiết. Việc sử dụng các rào cản bộ nhớ đòi hỏi phải nghiên cứu kỹ về kiến ​​trúc phần cứng và thường thấy trong trình điều khiển thiết bị hơn là mã ứng dụng.

Việc sắp xếp lại thứ tự của CPU khác với việc tối ưu hóa trình biên dịch - mặc dù các đồ tạo tác có thể giống nhau. Bạn cần thực hiện các biện pháp riêng biệt để dừng trình biên dịch sắp xếp lại các hướng dẫn của bạn nếu điều đó có thể gây ra hành vi không mong muốn (ví dụ: sử dụng từ khóa dễ bay hơi trong C).


26
Tôi không nghĩ rằng tính dễ bay hơi là đủ để ngăn trình biên dịch sắp xếp lại; AFAIK nó chỉ đảm bảo rằng trình biên dịch không thể lưu giá trị biến vào bộ nhớ cache. Nhân Linux sử dụng phần mở rộng gcc ( asm __volatile __ (""::: "memory")) để tạo ra một rào cản tối ưu hóa trình biên dịch đầy đủ.
CesarB

5
đúng, không ổn định là không thread biết nhưng bạn có thể sử dụng nó để ngăn chặn các trình biên dịch áp dụng optimisations nhất định - điều này không liên quan đến hàng rào;)
Gwaredd

3
(.NET CLR) đọc dễ bay hơi là hàng rào thu được, ghi là hàng rào phát hành. Các hoạt động được lồng vào nhau đã đầy như phương thức MemoryBarrier.
Luke Puplett

3
Thú vị đọc về từ khóa dễ bay hơi trong .net có thể được tìm thấy ở đây albahari.com/threading/part4.aspx#_NonBlockingSynch Các trang web chứa rất nhiều thông tin hữu ích về luồng trong c #
Bas Smit

developerWorks có một [bài báo] [1] hay về mô hình lưu trữ bộ nhớ PowerPC. [1]: ibm.com/developerworks/systems/articles/powerpc.html
Iouri Goussev

17

Sao chép câu trả lời của tôi cho một câu hỏi khác, Một số thủ thuật mà bộ xử lý thực hiện để tối ưu hóa mã là gì? :

Điều quan trọng nhất là sắp xếp lại quyền truy cập bộ nhớ.

Không có hàng rào bộ nhớ hoặc hướng dẫn tuần tự, bộ xử lý có thể tự do sắp xếp lại các truy cập bộ nhớ. Một số kiến ​​trúc bộ xử lý có giới hạn về số lượng chúng có thể sắp xếp lại; Alpha được biết đến là yếu nhất (tức là người có thể sắp xếp lại thứ tự nhiều nhất).

Có thể tìm thấy một cách xử lý rất tốt về chủ đề này trong tài liệu nguồn nhân Linux, tại Documentation / memory-domains.txt .

Hầu hết thời gian, tốt nhất là sử dụng khóa nguyên thủy từ trình biên dịch hoặc thư viện chuẩn của bạn; chúng được kiểm tra tốt, nên có tất cả các rào cản bộ nhớ cần thiết và có lẽ khá tối ưu hóa (việc tối ưu hóa khóa nguyên thủy rất khó; ngay cả các chuyên gia đôi khi cũng có thể làm sai).


Nó ảnh hưởng như thế nào đến dòng sắp xếp lại? Khi bạn nói Alpha is known for being the weakest, tại sao weakest? Nó không phải là tốt hơn, nó sắp xếp lại nhiều hơn, do đó nó sẽ được thực thi nhanh hơn nhiều? (Tôi không phải là người dùng alpha, nhưng hỏi về tác dụng của very reorderingvs restricted reordering). Vậy mặt trái của việc sắp xếp lại lô là gì (ngoại trừ rủi ro của hành vi không xác định, nhưng tôi đoán, hầu hết các CPU hiện đại nên giải quyết việc sắp xếp lại tốt và chỉ thực hiện việc sắp xếp lại được xác định, nếu không, nó sẽ không có ý nghĩa đối với quyết định mà họ đưa ra).
Herdsman

8

Theo kinh nghiệm của tôi, nó đề cập đến một rào cản bộ nhớ , là một chỉ dẫn (rõ ràng hoặc ngầm định) để đồng bộ hóa quyền truy cập bộ nhớ giữa nhiều luồng.

Vấn đề xảy ra trong sự kết hợp của các trình biên dịch hiện đại (chúng có quyền tự do đáng kinh ngạc để sắp xếp lại các hướng dẫn, nhưng thường không biết gì về các luồng của bạn) và các CPU đa lõi hiện đại.

Một phần giới thiệu hay về vấn đề này là " Tuyên bố 'Khóa được kiểm tra hai lần bị hỏng' ". Đối với nhiều người, đó là lời cảnh tỉnh rằng có rồng.

Rào cản bộ nhớ đầy tiềm ẩn thường được bao gồm trong các quy trình đồng bộ hóa luồng nền tảng, bao gồm cốt lõi của nó. Tuy nhiên, để lập trình không có khóa và triển khai các mẫu đồng bộ hóa tùy chỉnh, nhẹ, bạn thường chỉ cần rào cản, hoặc thậm chí chỉ cần rào cản một chiều.


2

Wikipedia biết tất cả ...

Hàng rào bộ nhớ, còn được gọi là thanh ghi nhớ hoặc hàng rào bộ nhớ, là một lớp lệnh khiến đơn vị xử lý trung tâm (CPU) thực thi ràng buộc thứ tự đối với các hoạt động bộ nhớ được cấp trước và sau lệnh rào cản.

CPU sử dụng các tính năng tối ưu hóa hiệu suất có thể dẫn đến việc thực thi không theo thứ tự, bao gồm tải bộ nhớ và các hoạt động lưu trữ. Việc sắp xếp lại hoạt động bộ nhớ thường không được chú ý trong một chuỗi thực thi duy nhất, nhưng gây ra hành vi không thể đoán trước trong các chương trình đồng thời và trình điều khiển thiết bị trừ khi được kiểm soát cẩn thận. Bản chất chính xác của một ràng buộc thứ tự là phụ thuộc vào phần cứng và được xác định bởi mô hình bộ nhớ của kiến ​​trúc. Một số kiến ​​trúc cung cấp nhiều rào cản để thực thi các ràng buộc đặt hàng khác nhau.

Rào cản bộ nhớ thường được sử dụng khi triển khai mã máy cấp thấp hoạt động trên bộ nhớ được chia sẻ bởi nhiều thiết bị. Mã như vậy bao gồm các nguyên thủy đồng bộ hóa và cấu trúc dữ liệu không khóa trên hệ thống đa xử lý và trình điều khiển thiết bị giao tiếp với phần cứng máy tính.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.