Tôi thực sự ngạc nhiên không ai có thể trả lời câu này, vì vậy ở đây chúng tôi đi trên một câu trả lời cụ thể phi Linux (Tôi không có đủ kiến thức về hạt nhân Linux chính nó cụ thể hơn) ...
cache snooping đơn giản chỉ yêu cầu bộ điều khiển DMA gửi yêu cầu vô hiệu hóa bộ nhớ cache tới tất cả các CPU cho bộ nhớ đang được DMA vào. Điều này rõ ràng là thêm tải vào bus coherency cache, và nó đặc biệt nặng với các bộ xử lý bổ sung vì không phải tất cả các CPU sẽ có một kết nối hop đơn với bộ điều khiển DMA phát hành snoop. Do đó, câu trả lời đơn giản cho "khi an toàn để vô hiệu hóa bộ nhớ cache snooping" là khi bộ nhớ được DMA vào hoặc không tồn tại trong bất kỳ bộ nhớ cache CPU HOẶC các dòng bộ nhớ cache của nó được đánh dấu là không hợp lệ. Nói cách khác, bất kỳ nỗ lực nào để đọc từ vùng DMAed sẽ luôn luôn dẫn đến đọc từ bộ nhớ chính.
Vậy làm thế nào để bạn đảm bảo đọc từ vùng DMA sẽ luôn chuyển sang bộ nhớ chính?
Quay trở lại những ngày trước khi chúng tôi có tính năng ưa thích như DMA snooping bộ nhớ cache, những gì chúng tôi đã từng làm là đường ống dẫn bộ nhớ DMA bằng cách cho ăn nó thông qua một loạt các giai đoạn chia tay như sau:
Giai đoạn 1: Thêm " dơ bẩn "vùng bộ nhớ DMA đến" bẩn và cần phải được làm sạch "danh sách bộ nhớ DMA.
Giai đoạn 2: Lần sau thiết bị ngắt với dữ liệu DMA mới, cấp bộ đệm CPU cục bộ không hợp lệ cho các phân đoạn DMA trong danh sách "bẩn và cần được làm sạch" cho tất cả các CPU có thể truy cập các khối đó (thường mỗi CPU chạy danh sách riêng của nó được tạo thành từ các khối bộ nhớ cục bộ). Di chuyển các phân đoạn đã nói vào danh sách "sạch".
Giai đoạn 3: DMA gián đoạn tiếp theo (dĩ nhiên bạn chắc chắn sẽ không xảy ra trước khi bộ nhớ cache đã hết hiệu lực), lấy vùng mới từ danh sách "sạch" và báo cho thiết bị biết rằng DMA tiếp theo của nó sẽ đi vào đó. Tái chế bất kỳ khối bẩn nào.
Giai đoạn 4: Lặp lại.
Vì đây là công việc nhiều hơn nên nó có một số lợi thế lớn. Thứ nhất, bạn có thể ghim xử lý DMA với một CPU đơn (thường là CPU0 chính) hoặc một nút SMP đơn lẻ, có nghĩa là chỉ một CPU/nút duy nhất cần phải lo lắng về việc mất hiệu lực bộ nhớ cache.Thứ hai, bạn cung cấp cho các hệ thống con bộ nhớ nhiều cơ hội hơn để ẩn thời gian trễ bộ nhớ cho bạn bằng cách giãn ra các hoạt động theo thời gian và trải rộng tải trên bus kết hợp bộ nhớ cache. Chìa khóa để thực hiện thường là thử và thực hiện bất kỳ DMA nào xảy ra trên CPU gần với bộ điều khiển DMA có liên quan nhất có thể và vào bộ nhớ càng gần CPU càng tốt.
Nếu bạn luôn luôn đưa DMA mới vào bộ nhớ cho không gian người dùng và/hoặc các CPU khác, chỉ cần nạp bộ nhớ mới mua vào ở phía trước của đường ống bộ đệm không hợp lệ bộ nhớ cache async. Một số hệ điều hành (không chắc chắn về Linux) có một thói quen được tối ưu hóa để đặt trước bộ nhớ zeroed, do đó hệ điều hành cơ bản không có bộ nhớ trong nền và giữ một bộ nhớ cache nhanh chóng xung quanh - nó sẽ trả cho bạn để giữ cho các yêu cầu bộ nhớ mới bên dưới. cực kỳ chậm. Tôi không biết về bất kỳ nền tảng nào được tạo ra trong mười năm qua sử dụng phần cứng bộ nhớ bị hỏng, do đó bạn phải giả định rằng tất cả bộ nhớ mới có thể chứa các dòng bộ nhớ cache hợp lệ cần vô hiệu.
Tôi đánh giá cao câu trả lời này chỉ một nửa câu hỏi của bạn, nhưng tốt hơn là không có gì. Chúc may mắn!
Niall
Đã có một số điều LWN về DMA và sự mạch lạc bộ nhớ cache bạn có thể muốn nhìn xung quanh trên lwn.net – Spudd86
Bạn đã đo hiệu suất đạt được bạn sẽ có được bằng cách tắt bộ nhớ cache snooping , không chỉ về việc chuyển giao mà còn trên toàn bộ ứng dụng? Sự kết hợp DMA rất thuận tiện và suy nghĩ về việc tương tác với phần cứng dễ dàng hơn nhiều đến nỗi tôi sẽ đo lường cẩn thận trước khi tắt nó đi. –