Tình hình chungLàm thế nào để mong muốn cam kết cấp phát bộ nhớ trong C + +?
Một ứng dụng cực kỳ chuyên sâu trên cả hai băng thông, sử dụng CPU, GPU và sử dụng cần phải chuyển về 10-15GB mỗi giây từ một GPU khác. Nó đang sử dụng API DX11 để truy cập GPU, do đó việc tải lên GPU chỉ có thể xảy ra với các bộ đệm yêu cầu ánh xạ cho mỗi lần tải lên duy nhất. Quá trình tải lên diễn ra theo khối lượng 25MB tại một thời điểm và 16 luồng đang ghi bộ đệm để ánh xạ bộ đệm đồng thời. Không có nhiều điều có thể được thực hiện về bất kỳ điều này. Mức độ đồng thời thực tế của các bài viết nên thấp hơn, nếu nó không phải vì lỗi sau.
Đó là một trạm làm việc mạnh mẽ với 3 GPU Pascal, bộ vi xử lý Haswell cao cấp và RAM bốn kênh. Không nhiều có thể được cải thiện trên phần cứng. Nó đang chạy một phiên bản máy tính để bàn của Windows 10.
Vấn đề thực tế
Khi tôi vượt qua ~ 50% CPU tải, một cái gì đó trong MmPageFault()
(bên trong nhân Windows, được gọi là khi truy cập vào bộ nhớ đã được ánh xạ vào của bạn không gian địa chỉ, nhưng không được hệ điều hành cam kết) phá vỡ khủng khiếp, và 50% tải CPU còn lại đang bị lãng phí trên một spin-lock bên trong MmPageFault()
. CPU sẽ được sử dụng 100% và hiệu năng của ứng dụng sẽ giảm hoàn toàn.
Tôi phải giả định rằng điều này là do số lượng bộ nhớ khổng lồ cần được phân bổ cho quá trình mỗi giây và cũng hoàn toàn không được ánh xạ từ quá trình mỗi khi bộ đệm DX11 chưa được ánh xạ. Tương ứng, nó thực sự là hàng ngàn cuộc gọi đến MmPageFault()
mỗi giây, xảy ra tuần tự như memcpy()
được viết tuần tự cho bộ đệm. Đối với mỗi trang không được cam kết gặp phải.
Một tải CPU vượt quá 50%, khóa spin lạc quan trong hạt nhân Windows bảo vệ quản lý trang hoàn toàn làm giảm hiệu suất một cách khôn ngoan.
cân nhắc
Bộ đệm được phân bổ bởi người lái xe DX11. Không có gì có thể được điều chỉnh về chiến lược phân bổ. Sử dụng một bộ nhớ khác nhau API và đặc biệt là tái sử dụng là không thể.
Cuộc gọi tới API DX11 (ánh xạ/hủy ánh xạ bộ đệm) tất cả xảy ra từ một chuỗi đơn lẻ. Các hoạt động sao chép thực tế có thể xảy ra đa luồng trên nhiều luồng hơn là có các bộ xử lý ảo trong hệ thống.
Giảm yêu cầu băng thông bộ nhớ là không thể. Đó là một ứng dụng thời gian thực. Trong thực tế, giới hạn cứng hiện là băng thông PCIe 3.0 16x của GPU chính. Nếu có thể, tôi sẽ cần phải đẩy mạnh hơn nữa.
Tránh không thể sao chép đa luồng, vì có hàng đợi người tiêu dùng sản xuất độc lập không thể hợp nhất một cách tầm thường.
Sự xuống cấp hiệu suất của khóa spin dường như quá hiếm (vì trường hợp sử dụng đang đẩy nó xa) trên Google, bạn sẽ không tìm thấy kết quả duy nhất cho tên của chức năng khóa quay.
Nâng cấp lên API cung cấp quyền kiểm soát nhiều hơn đối với ánh xạ (Vulkan) đang được tiến hành nhưng không phù hợp với tư cách là bản sửa lỗi ngắn hạn. Chuyển sang một hạt nhân hệ điều hành tốt hơn hiện không phải là một lựa chọn cho cùng một lý do.
Giảm tải CPU cũng không hoạt động; có quá nhiều công việc cần được thực hiện ngoài bản sao đệm (thường tầm thường và không tốn kém).
Các Câu hỏi
Có thể làm gì?
Tôi cần giảm đáng kể số lượng pagefaults riêng lẻ. Tôi biết địa chỉ và kích thước của bộ đệm đã được ánh xạ vào quá trình của tôi, và tôi cũng biết rằng bộ nhớ chưa được cam kết.
Làm cách nào để đảm bảo rằng bộ nhớ được cam kết với số lượng giao dịch ít nhất có thể?
Cờ lạ cho DX11 sẽ ngăn không phân bổ bộ đệm sau khi hủy ánh xạ, Windows API để bắt buộc thực hiện giao dịch đơn lẻ, khá nhiều điều được hoan nghênh.
Trạng thái hiện tại
// In the processing threads
{
DX11DeferredContext->Map(..., &buffer)
std::memcpy(buffer, source, size);
DX11DeferredContext->Unmap(...);
}
có vẻ như bạn đang ở khoảng 400 M cho tất cả 16 luồng cùng nhau. Khá thấp. Bạn có thể xác minh rằng bạn không vượt quá điều này trong ứng dụng của bạn? Tiêu thụ bộ nhớ là gì? Tôi tự hỏi nếu bạn có một rò rỉ bộ nhớ. – Serge
Mức tiêu thụ tối đa là khoảng 7-8GB, nhưng điều đó là bình thường, cho rằng tổng số đường ống xử lý cần> 1s đệm để bù đắp cho tất cả các loại tắc nghẽn. Có, đó là "chỉ" 400MB, 25 lần mỗi giây. Và nó hoạt động tốt, cho đến khi tải CPU cơ bản vượt quá 50% và hiệu năng của khóa spin đột ngột tăng đột biến từ 0 đến ~ 40-50% của việc sử dụng CPU hoàn chỉnh. Cũng ảnh hưởng đến các quá trình khác trên hệ thống cùng một lúc. – Ext3h
1. Bộ nhớ vật lý của bạn là gì? bạn có thể giết tất cả các quy trình hoạt động khác không? 2. đoán # 2 kể từ khi bạn nhìn thấy ngưỡng 50%, bạn có thể nhận được vào một số vấn đề với siêu phân luồng. Bạn có bao nhiêu lõi vật lý? số 8? Bạn có thể vô hiệu hóa siêu phân luồng không? Cố gắng chạy như nhiều chủ đề như có cpus vật lý trong trường hợp của bạn trên một máy sạch. – Serge