2010-09-20 23 views
14

Tôi đang làm việc trên một ứng dụng mà tuần tự viết một tập tin lớn (và không đọc ở tất cả), và tôi muốn sử dụng posix_fadvise() để tối ưu hóa hành vi hệ thống tập tin.Điều gì posix_fadvise() args cho ghi tập tin tuần tự?

Mô tả chức năng trong manpage gợi ý rằng chiến lược thích hợp nhất sẽ là POSIX_FADV_SEQUENTIAL. Tuy nhiên, mô tả triển khai Linux nghi ngờ rằng:

Trong Linux, POSIX_FADV_NORMAL đặt cửa sổ readahead thành kích thước mặc định cho thiết bị sao lưu; POSIX_FADV_SEQUENTIAL tăng gấp đôi kích thước này và POSIX_FADV_RANDOM vô hiệu hóa tệp được đọc hoàn toàn.

Vì tôi chỉ đang ghi dữ liệu (ghi đè lên các tệp có thể quá), tôi không mong đợi bất kỳ phần mềm đọc nào. Tôi có nên gắn bó với POSIX_FADV_SEQUENTIAL hoặc sử dụng POSIX_FADV_RANDOM để tắt nó không?

Còn các tùy chọn khác, chẳng hạn như POSIX_FADV_NOREUSE? Hoặc có thể không sử dụng posix_fadvise() để viết?

Trả lời

5

Tất cả phụ thuộc vào địa phương thời gian của dữ liệu của bạn. Nếu ứng dụng của bạn không cần dữ liệu ngay sau khi được viết, thì bạn có thể đi với POSIX_FADV_NOREUSE để tránh ghi vào bộ đệm đệm (theo cách tương tự như cờ O_DIRECT từ open()).

+8

Xin lưu ý rằng POSIX_FADV_NOREUSE không được triển khai trong hạt nhân Linux. – smoors

0

Theo như viết đi tôi nghĩ rằng bạn chỉ có thể dựa vào OSes đĩa IO scheduler để làm điều đúng.

Bạn nên nhớ rằng trong khi posix_fadvise là có đặc biệt để cung cấp cho các gợi ý hạt nhân về các mẫu sử dụng tệp trong tương lai, hạt nhân cũng có dữ liệu khác để giúp nó.

Nếu bạn không mở tệp để đọc thì nó sẽ chỉ cần đọc các khối khi chúng được viết một phần. Nếu bạn đã cắt bớt tệp thành 0 thì nó thậm chí không phải làm điều đó (bạn nói rằng bạn đã ghi đè).

32

Hầu hết các cờ posix_fadvise() (ví dụ: POSIX_FADV_SEQUENTIALPOSIX_FADV_RANDOM) là các gợi ý về readahead thay vì viết.

Có một số lời khuyên từ Linus herehere về việc nhận được hiệu suất ghi tuần tự tốt. Ý tưởng là để phá vỡ các tập tin vào cửa sổ lớn ish (8MB), sau đó vòng quanh làm:

  • Viết ra cửa sổ N với write();
  • Yêu cầu không đồng bộ ghi-out của cửa sổ N với sync_file_range(..., SYNC_FILE_RANGE_WRITE)
  • Chờ cho ghi-out của cửa sổ N-1 để hoàn thành với sync_file_range(..., SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)
  • cửa sổ Drop N-1 từ chủBộ nhớ đệm với posix_fadvise(..., POSIX_FADV_DONTNEED)

Bằng cách này bạn không bao giờ có nhiều hơn hai cửa sổ giá trị của dữ liệu trong bộ nhớ cache trang, nhưng bạn vẫn nhận được hạt nhân viết ra một phần của pagecache vào đĩa trong khi bạn điền vào phần tiếp theo.

+1

Tuyệt vời, đây là những gì tôi cần để làm cho utee (https: // github.com/aktau/utee) không làm nghẽn bộ đệm nhưng vẫn nhanh. Cảm ơn! – Aktau

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