2011-01-16 33 views
9

Tôi đang viết rất nhiều dữ liệu sẽ không được đọc lại trong nhiều tuần - vì chương trình của tôi chạy lượng bộ nhớ trống trên máy (được hiển thị với 'miễn phí' hoặc 'trên cùng') giảm rất nhanh, dung lượng bộ nhớ mà ứng dụng của tôi sử dụng không tăng - cũng không phải lượng bộ nhớ được sử dụng bởi các quy trình khác.I/O không được lọc trong Linux

Điều này khiến tôi tin rằng bộ nhớ đang bị bộ nhớ cache sử dụng bởi vì tôi không có ý định đọc dữ liệu này trong một thời gian dài. đĩa. Tôi không có ước mơ cải thiện perf hoặc là một ninja siêu, hy vọng của tôi là đưa ra một gợi ý cho hệ thống tập tin mà tôi sẽ không trở lại cho bộ nhớ này bất cứ lúc nào sớm, vì vậy không dành thời gian tối ưu hóa cho những trường hợp.

Trên Windows, tôi đã gặp phải sự cố tương tự và khắc phục sự cố bằng FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH - bộ nhớ máy không được ứng dụng của tôi tiêu thụ và máy có thể sử dụng được nhiều hơn nói chung. Tôi hy vọng sẽ lặp lại những cải tiến mà tôi đã thấy nhưng trên Linux. Trên Windows có sự hạn chế bằng văn bản trong các phần có kích thước theo ngành, tôi hài lòng với giới hạn này đối với số tiền đạt được mà tôi đã đo được.

có cách tương tự để thực hiện việc này trong Linux không?

Trả lời

6

Tương đương gần nhất với những lá cờ Windows bạn đề cập đến tôi có thể nghĩ là để mở tập tin của bạn với open(2) cờ O_DIRECT | O_SYNC:

O_DIRECT (Since Linux 2.4.10) 
      Try to minimize cache effects of the I/O to and from this file. In 
      general this will degrade performance, but it is useful in special 
      situations, such as when applications do their own caching. File I/O 
      is done directly to/from user space buffers. The O_DIRECT flag on its 
      own makes at an effort to transfer data synchronously, but does not 
      give the guarantees of the O_SYNC that data and necessary metadata are 
      transferred. To guarantee synchronous I/O the O_SYNC must be used in 
      addition to O_DIRECT. See NOTES below for further discussion. 

      A semantically similar (but deprecated) interface for block devices is 
      described in raw(8). 

Cấp, cố gắng để thực hiện nghiên cứu trên lá cờ này để xác nhận đó là những gì bạn muốn Tôi tìm thấy this interesting piece cho bạn biết rằng I/O không bị xâm phạm là một ý tưởng tồi, Linus mô tả nó là "bộ não bị hỏng". Theo đó, bạn nên sử dụng madvise() thay vì để cho hạt nhân làm thế nào để cache trang. YMMV.

2

như chương trình của tôi chạy dung lượng bộ nhớ miễn phí trên máy tính này giảm rất nhanh chóng

Tại sao điều này là một vấn đề? Bộ nhớ trống là bộ nhớ không phục vụ bất kỳ mục đích hữu ích nào. Khi nó được sử dụng để lưu trữ dữ liệu, ít nhất có một cơ hội nó sẽ hữu ích.

Nếu một trong các chương trình của bạn yêu cầu nhiều bộ nhớ hơn, bộ nhớ cache sẽ là điều đầu tiên cần thực hiện. Linux biết rằng nó có thể đọc lại dữ liệu đó từ đĩa bất cứ khi nào nó muốn, vì vậy nó sẽ gặt hái bộ nhớ và cho nó một cách sử dụng mới.

Đúng là Linux theo mặc định chờ khoảng 30 giây (đây là giá trị được sử dụng dù sao) trước khi xóa ghi vào đĩa. Bạn có thể tăng tốc độ này với một cuộc gọi đến fsync(). Nhưng một khi dữ liệu đã được ghi vào đĩa, có thực tế là zero chi phí để giữ bộ nhớ cache của dữ liệu trong bộ nhớ.

Thấy khi bạn ghi vào tệp và không đọc từ đó, Linux có thể đoán rằng dữ liệu này là tốt nhất để loại bỏ, tùy thuộc vào dữ liệu được lưu trong bộ nhớ cache khác. Vì vậy, đừng lãng phí nỗ lực cố gắng tối ưu hóa trừ khi bạn đã xác nhận rằng đó là một vấn đề hiệu suất.

+1

nó chỉ là một vấn đề bởi vì có hiệu lực là bộ nhớ cache đang được sử dụng cho thứ gì đó sẽ không bao giờ được sử dụng. Bộ nhớ cache được lấy từ những người khác có thể sử dụng và tôi thấy tăng I/O. – stuck

6

Bạn có thể sử dụng O_DIRECT, nhưng trong trường hợp đó, bạn cần tự mình thực hiện khối IO; bạn phải viết trong bội số của kích thước khối FS và trên ranh giới khối (có thể là nó không phải là bắt buộc nhưng nếu bạn không hiệu suất của nó sẽ hút x1000 bởi vì mỗi viết unaligned sẽ cần đọc trước).

Một cách ít tác động khác để ngăn chặn các khối sử dụng bộ nhớ cache của hệ điều hành mà không sử dụng O_DIRECT, là sử dụng posix_fadvise (fd, offset, len, POSIX_FADV_DONTNEED). Trong nhân Linux 2.6 hỗ trợ nó, điều này ngay lập tức loại bỏ (sạch) các khối từ bộ nhớ cache. Tất nhiên bạn cần phải sử dụng fdatasync() hoặc như vậy đầu tiên, nếu không các khối có thể vẫn bị bẩn và do đó sẽ không bị xóa khỏi bộ nhớ cache. Đây có lẽ là một ý tưởng tồi về fdatasync() và posix_fadvise (... POSIX_FADV_DONTNEED) sau mỗi lần viết, nhưng thay vào đó hãy chờ cho đến khi bạn đã thực hiện một số tiền hợp lý (50M, 100M có thể).

Vì vậy, trong ngắn

  • sau mỗi lần (đoạn đáng kể) của lần ghi,
  • Gọi fdatasync tiếp theo posix_fadvise (... POSIX_FADV_DONTNEED)
  • này sẽ xóa sạch các dữ liệu vào đĩa và ngay lập tức loại bỏ chúng từ bộ nhớ cache của hệ điều hành, để lại không gian cho những điều quan trọng hơn.

Một số người dùng nhận thấy những thứ như tệp nhật ký phát triển nhanh có thể dễ dàng phát tán nội dung "hữu ích" ra khỏi bộ nhớ cache, giúp giảm số lần truy cập bộ nhớ cache trên một hộp cần nhiều bộ nhớ cache , nhưng cũng viết nhật ký một cách nhanh chóng. Đây là động lực chính cho tính năng này.

Tuy nhiên, giống như bất kỳ tối ưu hóa

a) Bạn sẽ không cần nó để

b) Không làm điều đó (chưa)

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