2013-08-19 46 views
6

Câu hỏi này là theo dõi câu hỏi trước đó tôi đã đăng: Windows fsync (FlushFileBuffers) performance with large files. Nơi tôi tìm thấy một giải pháp có thể nhưng cũng là câu hỏi mới.Giải thích/tìm kiếm thông tin: Windows ghi hiệu suất I/O với "fsync" (FlushFileBuffers)

Trong khi đo điểm chuẩn các kịch bản khác nhau cho viết fsynced, tôi đã tìm thấy một số kết quả đáng ngạc nhiên. Tôi hy vọng một người nào đó có thể giúp giải thích hoặc chỉ cho tôi theo hướng thông tin giải thích những kết quả này.

Điểm chuẩn này là viết các khối ngẫu nhiên (trang 4096 byte lớn) vào một tệp theo tuần tự theo lô 8 trang (32 K) và sau đó xóa ghi. Nó viết tổng cộng 200.000 trang, tổng cộng là 800 MB và 25000 flushes. Kích thước của tệp được đặt thành độ dài cuối cùng của tệp trước khi bắt đầu ghi.

Nó hỗ trợ tổng cộng 4 lựa chọn, trong đó tất cả các tổ hợp đang chạy:

  • Để thực hiện một "fsync"/FlushFileBuffers hoạt động (FS) sau khi viết một lô hoặc một tuôn ra bình thường (NS).
  • Để ghi một byte đơn vào vị trí cuối cùng của tệp trước khi bắt đầu viết (LB) hoặc để trống tệp (E).
  • Để sử dụng tính năng ghi đệm bình thường (B) hoặc ghi đè/ghi đè (WT) viết (sử dụng FILE_FLAG_NO_BUFFERING và FILE_FLAG_WRITE_THROUGH).
  • Để ghi trực tiếp vào luồng tệp, tức là thông qua bộ xử lý tệp (F) hoặc ghi gián tiếp vào tệp bằng bản đồ bộ nhớ (MM).

Bảng bên dưới tóm tắt các phát hiện của tôi trên hệ thống (máy tính xách tay 64 bit Win 7 có đĩa trục chậm) cho tất cả các kết hợp của các tùy chọn này.

Benchmark results for all combinations of options

Những gì tôi thấy là việc thực hiện ghi đệm "fsynced" giảm theo hàm mũ với kích thước của tập tin vào một thông lượng cực kỳ thấp mà làm cho làm điều này không khả thi, kết hợp với các tập tin lớn. Nếu tệp có byte cuối cùng của nó được viết (tùy chọn LB), thông lượng thậm chí còn thấp hơn, vì vậy tôi sợ rằng ngẫu nhiên thay vì các kịch bản viết tuần tự, hiệu suất sẽ còn ấn tượng hơn nhiều.

Tuy nhiên đáng ngạc nhiên là với I/O không được nén/ghi lại, thông lượng vẫn không đổi, độc lập với kích thước của tệp. Ban đầu (100-200 MB đầu tiên) nó ở mức thông lượng thấp hơn so với việc ghi đệm, nhưng sau đó thông lượng trung bình bắt kịp nhanh chóng và nó kết thúc viết 800 MB nhanh hơn đáng kể. Thậm chí đáng ngạc nhiên hơn là nếu tệp có byte cuối cùng được viết, thông lượng tăng theo hệ số 2.

Khi ghi vào tệp thông qua tệp ánh xạ bộ nhớ, hiệu suất cũng giảm theo cùng hàm mũ, cũng có trong trường hợp tệp được mở bằng cờ không được nén/writethrough. Và ở đây là tốt, hiệu suất là tồi tệ hơn nếu tập tin có một byte bằng văn bản đến vị trí cuối cùng của nó.

CẬP NHẬT Dựa trên giải thích Howard herehere, tôi reran các thử nghiệm mà không cần tạo một file mới trước khi bắt đầu ghi (ví dụ: mở, tập tin văn bản đầy đủ hiện có và ghi đè lên nó). Tôi đã cập nhật mã trong câu hỏi ban đầu của mình để phản ánh các thay đổi được thực hiện cho thử nghiệm này. Kết quả là một phần phù hợp với lời giải thích và phát hiện của mình trên Linux. Nhưng có một số ngoại lệ đáng chú ý. Bảng dưới đây cung cấp kết quả, màu đỏ làm nổi bật những thay đổi quan trọng, những điểm nổi bật màu xanh ở những thay đổi không xảy ra và điều này thật đáng ngạc nhiên (tức làkhông phù hợp với kỳ vọng nếu các hiệu ứng được đề cập trong lời giải thích của Howard là những tác dụng duy nhất được chơi).

Results when overwriting existing file

Đối với đệm ghi vào tập tin (ví dụ: không thông qua memmap) với một "fsync" tuôn ra, việc thực hiện tại đã thay đổi từ theo cấp số nhân mục nát đến một xu hướng không đổi. Tuy nhiên, nó mất nhiều thời gian hơn trong các kịch bản thử nghiệm trước đó. Thông lượng là một hằng số 1,5 MB/s, trong đó trước khi nó bắt đầu vào khoảng 20 MB/s để phân rã theo cấp số nhân khoảng 1,5 MB/s. Nó sẽ xuất hiện rằng một lời giải thích có thể là siêu dữ liệu tập tin cũng được flushed trên mỗi tuôn ra, gây ra một cuộc cách mạng đĩa đầy đủ để tìm kiếm vị trí của siêu dữ liệu.

Để ghi "" thông qua các tình huống tệp, kết quả để viết byte cuối cùng hay không, giờ đã giống hệt nhau, phù hợp với những gì được mong đợi từ lời giải thích của Howard.

Tuy nhiên, ghi vào bản đồ bộ nhớ, với một ngoại lệ đáng chú ý, đã không thực sự thay đổi và điều này thật đáng ngạc nhiên. Chúng vẫn cho thấy sự phân rã theo cấp số nhân trong việc ghi hiệu suất (bắt đầu vào khoảng 20 MB/s phân rã xuống còn 1,8 MB/s). Điều này sẽ gợi ý rằng một cơ chế khác đang diễn ra. Một ngoại lệ đáng chú ý là nếu tập tin cơ bản được tạo ra mà không có FILE_FLAG_WRITE_THROUGH và "fsync" flushes được thực hiện. Kịch bản này bây giờ cho thấy một hiệu suất không đổi (nghèo) với thông lượng khoảng 1,6 MB/s. Vì tôi đã có một số nghi ngờ, tôi đọc lại kịch bản này nhiều lần, cho cùng một kết quả mỗi lần.

Để tìm hiểu thêm một chút, tôi cũng kiểm tra lại bằng cách sử dụng tệp nhỏ hơn (50000 trang, tổng cộng 200 MB) để xác nhận rằng hiệu suất fsync (cho đệm I/O) thực sự phụ thuộc vào kích thước tệp . Các kết quả được hiển thị bên dưới, với những kết quả đáng chú ý đặc biệt được đánh dấu bằng màu đỏ.

Results on smaller file

Những kết quả tương quan tốt với những gì đã được nhìn thấy các tập tin lớn hơn. Những thay đổi đáng chú ý là việc viết có hiệu suất cao hơn một chút cho những người được đánh dấu, nơi chúng dường như đạt đến giới hạn khoảng 7 MB/s.

Tóm tắt như tính đầu cơ cao kết luận dựa trên quan sát vào sytem tôi cho đến nay:

  • "fsync" hiệu suất trên các cửa sổ trên các tập tin với đệm IO (tức là không cờ FILE_FLAG_WRITE_THROUGH) được theo cấp số nhân giảm với số byte đã được ghi vào tệp. Lý do có vẻ là cần phải xóa siêu dữ liệu tệp mỗi lần, điều này làm cho đĩa tìm kiếm phần đầu của tệp.
  • hiệu suất "fsync" trên cửa sổ khi ghi vào tệp ánh xạ bộ nhớ cũng cho thấy hiệu suất giảm theo cấp số nhân. Tôi hiện không có lời giải thích cho cơ chế chính xác gây ra điều này.

Với hiệu suất được quan sát này, ít nhất cho trường hợp sử dụng của tôi, hai tùy chọn I/O này sẽ không thể hiện các giải pháp khả thi.

Theo Greg's suggestion Tôi sẽ chạy lại kiểm tra với tính năng lưu trong bộ nhớ đệm của ổ đĩa, và tôi cũng sẽ chạy số benchmark code của Howard để loại trừ khả năng kết quả bị sai lệch do lỗi của riêng tôi.

CẬP NHẬT 2 Tôi đã hoàn thành các bài kiểm tra và hiện đang biên soạn kết quả.Để không viết "lịch sử đầy đủ của" tôi sẽ thay thế các nội dung hiện tại của câu hỏi này bằng một bản tóm tắt các kết quả, phát hiện và một số kết luận. Câu trả lời của Howard về câu hỏi này, và khả năng chạy mã điểm chuẩn c của mình bên cạnh mã .NET là hữu ích nhất. Kết quả của những ứng dụng đó tương quan khá tốt. Câu trả lời của Rlb đã giúp tôi có được cảm giác tốt hơn về những "số hợp lý" liên quan đến đĩa. Cảm ơn.

Một phần của câu hỏi vẫn chưa được trả lời. Đặc biệt liên quan đến hiệu suất giảm (và kích thước tập tin phụ thuộc) quan sát được khi ghi vào bản đồ bộ nhớ. Nó có thể liên quan đến việc tìm kiếm/siêu dữ liệu tuôn ra, nhưng nó vẫn chưa rõ ràng với tôi tại sao/như thế nào.

+0

Nếu bạn đóng tmpfile ngay trước khi bộ sưu tập thời gian báo cáo cuối cùng của bạn, điều này không làm thay đổi con số? Một vài kết quả của bạn rất thú vị, vì vậy có thể thử và tái tạo. Thứ tự bạn chạy kịch bản có hiệu lực không? – rlb

+0

Tệp tạm thời bị đóng. Việc xây dựng đó được sử dụng để tạo một tệp trống mới, đặt độ dài của nó và tùy ý điền vào byte cuối cùng. Sau đó nó được đóng lại. Tệp được mở lại trước khi bắt đầu ghi. – Alex

+0

@rlb và không có thứ tự nào không có hiệu lực thực. Vì chúng ta tạo tập tin từ đầu mỗi lần và điền nó với các byte ngẫu nhiên, không có hiệu ứng bộ nhớ đệm nào xảy ra. Chạy một kịch bản độc lập mang lại kết quả tương tự. – Alex

Trả lời

4

Bạn đang thấy tốc độ giảm theo cấp số nhân trên đồng bộ hóa vì các giá trị này không hoàn toàn là khối lượng công việc tuần tự như bạn tin. Vì bạn bắt đầu với một tệp mới mỗi lần, các ghi của bạn đang phát triển tệp và siêu dữ liệu cần phải được cập nhật trong hệ thống tệp. Điều đó đòi hỏi nhiều tìm kiếm và khi tệp phát triển các tìm kiếm từ cuối tệp đến siêu dữ liệu mất nhiều thời gian hơn và lâu hơn. Tôi cũng đã đăng câu hỏi này lên câu hỏi khác của bạn do nhầm lẫn, hãy xem câu trả lời đầy đủ ở đó: https://stackoverflow.com/a/18429712/894520

0

Thử tắt bộ nhớ đệm đĩa và đăng lại?

Nếu không, các số liệu này là vô nghĩa (Fsync và ghi thông qua có thể không thực sự nhấn đĩa). Windows bằng cách mặc định cho phép đĩa bộ nhớ đệm điều khiển bộ nhớ đệm ..

Greg

+0

FlushFileBuffers được cho là xóa bộ đệm điều khiển. Đó là điểm của bài tập. –

+0

Greg, theo kinh nghiệm của bạn là trường hợp lệnh "SYNCHRONIZE CACHE" hoặc "FLUSH CACHE" không được các thiết bị hỗ trợ khi 'FlushFileBuffers' được phát hành? Hoặc hệ thống tập tin hệ điều hành lưu trữ không được flushed như là kết quả của 'FlushFileBuffers'. I E. những gì sẽ là lý do cho việc vô hiệu hóa các cửa sổ bộ nhớ đệm đĩa hoàn toàn? – Alex

+0

Hoặc là nó liên quan đến thực tế là lên đến và bao gồm Win 7/Server 2008 R2 chỉ được sử dụng "Force Unit Access" để xóa siêu dữ liệu NTFS? – Alex