2012-05-14 46 views
5

Sự hiểu biết của tôi về cách các tệp ánh xạ bộ nhớ hoạt động trong C# là mọi yêu cầu cho kết quả dữ liệu trong một bản sao. Ví dụ, nếu bạn có một cấu trúc dữ liệu lớn tồn tại dưới dạng một tệp, việc sử dụng tệp ánh xạ bộ nhớ sẽ dẫn đến bộ nhớ cho tệp thực được ánh xạ vào RAM và bản sao nằm trong đống GC khi nó được đọc từ tệp.Có thể tránh các bản sao dữ liệu khi sử dụng các tệp ánh xạ bộ nhớ trong C# không?

Tôi giả định điều này là do con trỏ và GC không hòa hợp với nhau nói chung.

Vì vậy, có cách nào xung quanh vấn đề này không?

  • Có thể qua một số chế độ hỗn hợp C++ có thể hiển thị API được quản lý trên dữ liệu được ánh xạ bộ nhớ?
  • Điều gì về thao tác trỏ trực tiếp với C# không an toàn?

Vấn đề chung mà tôi đang cố giải quyết là chia sẻ cấu trúc dữ liệu lớn giữa nhiều quy trình. Cấu trúc dữ liệu được sử dụng để trả lời một tập hợp nhỏ các "câu hỏi" có thể được hiển thị dưới dạng một API đơn giản (tức là về cơ bản, một chỉ mục rất chuyên môn về một loạt các dữ liệu khác).

Một lưu ý phụ, điều này không làm cho API .NET vô dụng đối với trường hợp "chia sẻ lượng lớn dữ liệu"?

+1

http://code.msdn.microsoft.com/windowsdesktop/Inter-process-communication-e96e94e7 –

+0

Bạn có đọc toàn bộ tệp cùng lúc trong ứng dụng .NET không? Nếu bạn đang đọc các phần của tệp ánh xạ bộ nhớ, khi cần, bạn phân bổ rất nhiều bộ đệm nhỏ, nhưng điều này không đắt như bạn nghĩ. Có thể tránh tạo bản sao, nhưng chi phí làm bản sao có thực sự là vấn đề không? –

+0

Tôi có các ứng dụng .NET rất hiệu quả "chia sẻ một lượng lớn dữ liệu" theo nhiều cách, bao gồm các tệp được ánh xạ bộ nhớ. Cụ thể, một bộ chia sẻ lên tới 8 gigabyte và tổng dung lượng bộ nhớ của các chương trình đó đáng ngạc nhiên là gần 8 gigabyte. –

Trả lời

4

Bạn có thể sử dụng mã không an toàn để truy cập trực tiếp bộ nhớ được ánh xạ. Tôi đề nghị bạn nhìn vào "cấu trúc blittable" là các loại cấu trúc có thể được sao chép xung quanh trong bộ nhớ mà không sửa đổi. Dưới đây là ví dụ:

struct MyDataRecord { public int X, Y; } 

... 

for (var i = 0 .. 10) { 
((MyDataRecord*)pointerToUnmanagedMemory)[i] = new MyDataRecord() { X = i, Y = i * i }; 
} 

Điều này rất hiệu quả và tiện lợi.

+0

Hmm, bạn bỏ qua mutex có tên bạn cần đảm bảo rằng một quá trình không đọc dữ liệu đang được ghi. Điều đó có một sở trường để ném "thuận tiện" ra khỏi cửa sổ. Và giết người. –

+0

Có vẻ như mã không an toàn và cấu trúc dễ vỡ sẽ là con đường để đi ... Cảm ơn @usr. Tôi cũng tìm thấy điều này sau khi bao gồm "không an toàn" trong tìm kiếm của mình: http://stackoverflow.com/questions/7956167/how-can-i-quickly-read-bytes-from-a-memory-mapped-file-in-net – David

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