2009-06-18 30 views
5

Tôi đang làm việc trên một phần mềm khoa học rất chuyên sâu (ràng buộc proc), nhưng nó cần phải ghi dữ liệu vào đĩa khá thường xuyên (i/o bị ràng buộc).Cách hiệu quả để lưu dữ liệu vào đĩa trong khi đang chạy một tác vụ tính toán chuyên sâu

Tôi đang thêm song song với điều này (OpenMP) và tôi tự hỏi cách tốt nhất để giải quyết nhu cầu ghi vào đĩa là gì. Không có lý do nào mô phỏng nên đợi trên HDD (đó là những gì nó đang làm bây giờ).

Tôi đang tìm một 'thực hành tốt nhất' cho điều này, và tốc độ là những gì tôi quan tâm nhất (đây có thể là những mô phỏng cực kỳ dài).

Cảm ơn ~ Alex

suy nghĩ đầu tiên:

có một quá trình riêng biệt làm văn bản thực tế vào đĩa để mô phỏng có hai quá trình: một là CPU-bound (mô phỏng) và một là IO-bound (ghi tệp). Điều này nghe có vẻ phức tạp.

Có thể là đường ống/bộ đệm? Tôi là loại mới, vì vậy có lẽ đó có thể là một giải pháp khả thi.

Trả lời

2

Nếu bạn thực hiện OpenMP để chương trình của bạn, sau đó nó là tốt hơn để sử dụng #pragma OMP đơn hoặc #pragma OMP chủ từ phần song song để lưu vào tập tin. Những pragmas này chỉ cho phép một luồng để thực thi một cái gì đó. Vì vậy, mã của bạn có thể trông giống như sau:

#pragma omp parallel 
{ 
    // Calculating the first part 
    Calculate(); 

    // Using barrier to wait all threads 
    #pragma omp barrier 

    #pragma omp master 
    SaveFirstPartOfResults(); 

    // Calculate the second part 
    Calculate2(); 

    #pragma omp barrier 

    #pragma omp master 
    SaveSecondPart(); 

    Calculate3(); 

    // ... and so on 
} 

Nhóm chủ đề này sẽ tính toán, nhưng chỉ có một chuỗi sẽ lưu kết quả vào đĩa.

Dường như đường ống phần mềm. Tôi đề nghị bạn nên xem xét tbb :: mô hình đường ống từ thư viện Intel Threading Building Blocks. Tôi có thể giới thiệu bạn đến hướng dẫn về đường ống phần mềm tại http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25. Vui lòng đọc đoạn 4.2. Họ giải quyết vấn đề: một chủ đề để đọc từ ổ đĩa, thứ hai để xử lý chuỗi đọc, thứ ba để lưu vào ổ đĩa.

5

Tôi muốn nói cách tốt nhất là tạo ra một luồng khác để lưu dữ liệu chứ không phải một quy trình hoàn toàn mới; với một quy trình mới, bạn gặp phải sự cố khi phải truyền dữ liệu được lưu qua ranh giới quy trình, giới thiệu một tập hợp các khó khăn mới.

0

Một luồng liên tục thực hiện một bước của quy trình tính toán chuyên sâu và sau đó thêm kết quả một phần vào hàng đợi kết quả một phần. Một luồng khác liên tục loại bỏ một phần kết quả khỏi hàng đợi và ghi chúng vào đĩa. Đảm bảo đồng bộ hóa quyền truy cập vào hàng đợi. Hàng đợi là cấu trúc dữ liệu giống như danh sách, nơi bạn có thể thêm các mục vào cuối và xóa các mục khỏi mặt trước.

1

Vì bạn là CPU và IO bị ràng buộc: Hãy để tôi đoán: Vẫn còn rất nhiều bộ nhớ có sẵn, phải không?

Nếu vậy bạn nên đệm dữ liệu phải được ghi vào đĩa trong bộ nhớ theo một khoảng thời gian nhất định. Viết các khối dữ liệu khổng lồ thường nhanh hơn rất nhiều so với việc viết các mẩu nhỏ.

Để tự viết: Xem xét sử dụng bộ nhớ ánh xạ IO. Đã một thời gian kể từ khi tôi được điểm chuẩn, nhưng lần cuối tôi làm điều đó nhanh hơn đáng kể.

Ngoài ra, bạn luôn có thể giao dịch CPU so với IO một chút. Tôi nghĩ bạn hiện đang viết dữ liệu dưới dạng một số dữ liệu thô, không nén, phải không? Bạn có thể nhận được một số hiệu suất IO nếu bạn sử dụng một lược đồ nén đơn giản để giảm lượng dữ liệu được ghi. Thư viện ZLIB khá dễ làm việc và nén rất nhanh ở mức nén thấp nhất. Nó phụ thuộc vào bản chất của dữ liệu của bạn, nhưng nếu có rất nhiều dự phòng trong nó ngay cả một thuật toán nén rất thô có thể loại bỏ vấn đề liên kết IO.

3

Giải pháp đầu tiên xuất hiện trong đầu là khá nhiều những gì bạn đã nói - có ghi đĩa trong quá trình của riêng chúng với một đường ống một chiều từ sim đến người viết. Người viết viết nhanh nhất có thể (vẽ dữ liệu mới ra khỏi đường ống). Vấn đề với điều này là nếu sim quá xa phía trước của nhà văn, sim sẽ được chặn trên đường ống viết anyway, và nó sẽ được I/O ràng buộc tại một loại bỏ.

Vấn đề là trên thực tế chu kỳ mô phỏng của bạn chưa hoàn thành cho đến khi nó nhổ ra các kết quả.

Điều thứ hai xảy ra với tôi là sử dụng I/O không chặn.Bất cứ khi nào sim cần viết, nó sẽ làm như vậy thông qua I/O không bị chặn. Về nhu cầu tiếp theo cần viết, sau đó nó có thể nhận các kết quả của hoạt động I/O trước đó (có thể xảy ra một sự chờ đợi nhỏ) trước khi bắt đầu một cái mới. Điều này giúp mô phỏng chạy càng nhiều càng tốt song song với I/O mà không cho phép mô phỏng đạt được rất xa so với văn bản.

Giải pháp đầu tiên sẽ tốt hơn nếu chu kỳ xử lý mô phỏng thay đổi (đôi khi nhỏ hơn thời gian viết, đôi khi lâu hơn) vì trung bình ghi có thể theo kịp với sim.

Nếu chu trình xử lý luôn luôn (hoặc gần như luôn luôn) sẽ ngắn hơn thời gian ghi thì bạn cũng có thể không bận tâm với đường ống và chỉ sử dụng I/O không chặn, vì nếu bạn sử dụng đường ống nó sẽ dần dần lấp đầy và sim sẽ bị treo lên trên I/O anyway.

+0

Tôi nghĩ ống 1 chiều là cách tôi sẽ đi. Tôi không nghĩ rằng tôi sẽ chạy vào vấn đề chặn quá nặng; theres không phải là rất nhiều dữ liệu được tạo ra, tôi chỉ muốn tách các chủ đề. Nếu tôi tạo ra nhiều dữ liệu, tôi sẽ xem xét lại số tiền thực sự cần được lưu giữ. – machinaut

0

Làm cho ứng dụng của bạn có hai chủ đề , một cho CPU và một cho đĩa cứng.

Có CPU chủ đề đẩy hoàn thành dữ liệu vào một hàng đợi mà thread đĩa cứng sau đó kéo từ dưới dạng dữ liệu đến.

Bằng cách này, CPU chỉ được thoát khỏi những dữ liệu và cho phép người khác xử lý nó và cứng lái xe kiên nhẫn chờ đợi bất kỳ dữ liệu nào trong hàng đợi của nó.

Thực hiện khôn ngoan, bạn có thể thực hiện hàng đợi dưới dạng loại bộ nhớ được chia sẻ của đối tượng, nhưng tôi nghĩ rằng một đường ống sẽ chính xác là những gì bạn sẽ tìm kiếm. CPU chỉ viết vào đường ống khi cần. Về phía đĩa cứng, bạn sẽ chỉ đọc đường ống và bất cứ khi nào bạn có dữ liệu hợp lệ, hãy tiếp tục từ đó.

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