6

Tuyên bố miễn trừ trách nhiệm: Tôi xin lỗi vì tính đầy đủ của câu hỏi này (tôi nghĩ đó là một vấn đề thú vị!), Nhưng tôi không thể hiểu để chính xác hơn từ nó.Truy cập> 2,3,4 GB tệp trong quy trình 32bit trên 64bit (hoặc 32bit) Windows

Tôi đã làm giờ nghiên cứu như các rõ ràng vô số cách thức để giải quyết vấn đề truy cập vào các tập tin đa GB trong một quá trình 32bit trên 64bit Windows 7, từ /LARGEADDRESSAWARE để VirtualAllocEx AWE. Tôi hơi thoải mái khi viết một hệ thống ánh xạ nhiều bộ nhớ trong Windows (CreateFileMapping, MapViewOfFile, vv), nhưng không thể thoát khỏi cảm giác rằng có một giải pháp thanh lịch hơn cho vấn đề này. Ngoài ra, tôi khá ý thức về các mẫu interprocess và iostream của Boost, mặc dù chúng có vẻ khá nhẹ, đòi hỏi một lượng nỗ lực tương tự để viết một hệ thống chỉ sử dụng các cuộc gọi Windows API (chưa kể đến thực tế là tôi đã có bộ nhớ) kiến trúc được ánh xạ bán thực hiện bằng cách sử dụng các cuộc gọi API Windows).

Tôi đang cố xử lý các tập dữ liệu lớn. Chương trình này phụ thuộc vào các thư viện 32 bit được biên dịch trước, đó là lý do tại sao, hiện tại chương trình cũng đang chạy trong một tiến trình 32 bit, mặc dù hệ thống là 64bit, với hệ điều hành 64 bit. Tôi biết có những cách mà tôi có thể thêm các thư viện bao quanh này, tuy nhiên, nhìn thấy như nó là một phần của một codebase lớn hơn, nó thực sự sẽ là một chút của một cam kết. Tôi đặt tiêu đề nhị phân để cho phép /LARGEADDRESSAWARE (với chi phí giảm không gian hạt nhân của tôi?), Như vậy tôi nhận được khoảng 2-3 GB bộ nhớ địa chỉ cho mỗi quá trình, cho hoặc nhận (tùy thuộc vào phân đoạn heap, v.v.) .

Đây là vấn đề: bộ dữ liệu là 4 + GB và có thuật toán DSP chạy trên chúng yêu cầu truy cập ngẫu nhiên cơ bản trên tệp. Một con trỏ tới đối tượng được tạo ra từ tệp được xử lý trong C#, nhưng bản thân tệp được nạp vào bộ nhớ (với hệ thống ánh xạ bộ nhớ một phần này) trong C++ (đó là P/Invoked). Do đó, tôi tin rằng giải pháp không may đơn giản như điều chỉnh cửa sổ để truy cập vào phần của tệp mà tôi cần truy cập, vì về cơ bản tôi vẫn muốn toàn bộ tệp được trừu tượng thành một con trỏ, từ đó tôi có thể gọi các phương thức để truy cập dữ liệu gần như mọi nơi trong tệp. Rõ ràng, hầu hết các kiến ​​trúc được ánh xạ bộ nhớ dựa vào việc tách quy trình số ít thành nhiều tiến trình .. vì vậy, ví dụ, tôi truy cập một tệp 6 GB với quy trình 3x, mỗi cửa sổ chứa 2 GB vào tệp. Sau đó tôi sẽ cần phải thêm một số lượng đáng kể logic để kéo và kết hợp lại dữ liệu từ các cửa sổ/quy trình khác nhau này. VirtualAllocEx dường như cung cấp một phương pháp để tăng không gian địa chỉ ảo, nhưng tôi vẫn không hoàn toàn chắc chắn nếu đây là cách tốt nhất để đi về nó.

Nhưng, giả sử tôi muốn chương trình này hoạt động giống như "dễ dàng" như một lần truy cập 64 bit số ít trên hệ thống 64 bit. Giả sử rằng tôi không quan tâm đến việc đập, tôi chỉ muốn có thể thao tác một tệp lớn trên hệ thống, ngay cả khi chỉ, nói, 500 MB đã được nạp vào RAM vật lý tại một thời điểm. Có cách nào để có được chức năng này mà không cần phải viết một hệ thống bộ nhớ thủ công hơi vô lý bằng tay? Hoặc, là có một số cách tốt hơn so với những gì tôi đã tìm thấy thông qua suchfar chải SO và internet?

Điều này cho chính câu hỏi thứ hai: có cách nào hạn chế lượng RAM vật lý sẽ được sử dụng bởi quy trình này không? Ví dụ, nếu tôi muốn giới hạn quá trình chỉ có 500 MB được nạp vào RAM vật lý tại bất kỳ thời điểm nào (trong khi vẫn giữ tệp nhiều GB được phân trang trên đĩa)?

Tôi xin lỗi vì câu hỏi dài, nhưng tôi cảm thấy đó là một bản tóm tắt về những gì dường như là nhiều câu hỏi (chỉ với một phần câu trả lời) mà tôi đã tìm thấy trên SO và mạng lưới. Tôi hy vọng rằng đây có thể là một khu vực trong đó một câu trả lời dứt khoát (hoặc ít nhất là một số ưu/nhược điểm) có thể được giải quyết, và tất cả chúng ta đều có thể học được điều gì đó có giá trị trong quá trình này!

+1

tl; dr, nhưng nếu bạn muốn sử dụng thư viện bên ngoài: Qt có thể xử lý nền tảng "tệp lớn", mặc dù không được ánh xạ bộ nhớ (trên nền tảng 32 bit). Nhưng nó sử dụng bộ nhớ đệm IO bên trong mà * có thể * đạt được hiệu suất tương đương? – leemes

+0

Cảm ơn các bình luận, leemes (mặc dù tl; dr là một chút của một điều thô lỗ để nói> _> ;;)! Tôi đã xem xét sử dụng một bộ nhớ đệm IO nội bộ, nhưng điều này có vẻ như giới thiệu một số tiền hợp lý phức tạp, đó là những gì tôi đang cố gắng tránh. Ngoài ra, tôi muốn tránh thêm các thư viện bổ sung như Qt vào hỗn hợp (Boost đã được tích hợp, mặc dù) –

+0

Hạn chế RAM, bạn có thể sử dụng một đối tượng công việc Windows và giới hạn bộ làm việc, đó là hạn chế RAM vật lý. Thật không may tôi nghĩ rằng điều này sẽ chỉ tối đa hóa trao đổi, vì vậy nó không phải là những gì bạn có thể muốn. Tôi cũng giả sử bạn biết về các tệp ánh xạ bộ nhớ và chúng không phù hợp với nhu cầu của bạn. –

Trả lời

2

Bạn có thể viết lớp truy cập mà bạn cung cấp cho nó địa chỉ cơ sở và độ dài. Nó trả về dữ liệu hoặc ném ngoại lệ (hoặc tuy nhiên khác bạn muốn thông báo về điều kiện lỗi) nếu điều kiện lỗi phát sinh (ngoài giới hạn, vv).

Sau đó, bất cứ lúc nào bạn cần đọc từ tệp, đối tượng truy cập có thể sử dụng SetFilePointerEx() trước khi gọi ReadFile(). Sau đó, bạn có thể vượt qua lớp truy cập tới hàm tạo của bất kỳ đối tượng nào bạn tạo khi bạn đọc tệp. Các đối tượng sau đó sử dụng lớp accessor để đọc dữ liệu từ tệp. Sau đó, nó trả về dữ liệu cho hàm tạo của đối tượng để phân tích nó thành dữ liệu đối tượng.

Nếu sau đó xuống dòng, bạn có thể biên dịch sang 64 bit, bạn chỉ có thể thay đổi (hoặc mở rộng) lớp accessor để đọc từ bộ nhớ thay thế.

Để hạn chế số lượng RAM được sử dụng bởi quy trình .. chủ yếu là đảm bảo rằng A) bạn không bị rò rỉ bộ nhớ (đặc biệt là những lời khiêu dâm) và B) phá hủy các đối tượng bạn không cần ngay lúc này. Ngay cả khi bạn sẽ cần nó sau này xuống dòng nhưng dữ liệu sẽ không thay đổi ... chỉ phá hủy đối tượng. Sau đó tạo lại sau khi bạn cần, cho phép nó đọc lại dữ liệu từ tệp.

+1

Hmm ... điều này nghe có vẻ như một ý tưởng thú vị, inetknght! Cảm ơn bạn đã nhập! Mặc dù điều này nghe có vẻ giống như một cách tuyệt vời để đọc qua tệp, nó vẫn sẽ yêu cầu bổ sung một lượng logic hợp lý để di chuyển chế độ xem theo cách thủ công trên tệp, mặc dù tôi đồng ý rằng việc sử dụng trình truy cập có thể mở rộng sẽ rất tuyệt vời rằng chỉ có lớp accessor sẽ phải được sửa đổi nếu điều này bao giờ được di chuyển về phía 64-bit. Điều này có thể kết thúc là việc thực hiện cuối cùng, nếu không có bất kỳ cách nào khác để dễ dàng có tệp được quản lý bởi một số cấu trúc khác. –

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