Buộc thư mục phải luôn trong bộ nhớ cache


35

Tôi đã thử nghiệm các phương pháp khác nhau để cải thiện thời gian cần thiết để biên dịch toàn bộ dự án c ++ của tôi. Hiện tại phải mất ~ 5 phút. Tôi đã thử nghiệm với distcc, ccache và những người khác. Gần đây, tôi phát hiện ra rằng nếu tôi sao chép toàn bộ dự án của mình vào ổ đĩa RAM và sau đó biên dịch từ đó, nó sẽ giảm thời gian biên dịch xuống còn 30% so với ban đầu - chỉ 1,5 phút.

Rõ ràng, làm việc từ ổ đĩa RAM là không thực tế. Vì vậy, có ai biết một cách tôi có thể buộc HĐH luôn giữ một thư mục nhất định được lưu trữ không? Tôi vẫn muốn thư mục được đồng bộ hóa trở lại vào đĩa như bình thường, nhưng tôi luôn muốn có một bản sao của dữ liệu trong bộ nhớ. Điều này có thể không?

EDIT: Là một giải pháp khả thi, chúng tôi chỉ nghĩ đến việc khởi chạy một daemon chạy rsynccứ sau 10 giây hoặc lâu hơn để đồng bộ hóa ổ đĩa với ổ đĩa RAM. Sau đó, chúng tôi chạy biên dịch từ ổ đĩa RAM. Việc rsyncnày rất nhanh, nhưng điều này có thực sự hiệu quả không? Chắc chắn HĐH có thể làm tốt hơn ....


Cache không phải là sự khác biệt duy nhất giữa tmpfs và ext3 / 4; họ có nhật ký, ví dụ, sẽ được viết bất kể bộ nhớ đệm.
André Paramés

1
Bạn có thể timebiên soạn và chia sẻ kết quả với chúng tôi không? Nó sẽ xua tan một số tranh cãi nâng cao. make clean && /usr/bin/time -v make(không sử dụng lệnh bash được xây dựng time)
shellholic

1
@she Tại sao không có lệnh tích hợp của bash?
tshepang

3
@Tshepang, timebash ( help time) tích hợp có ít chi tiết hơn (không có tùy chọn dài dòng) so với thời gian GNU ( man time) liên quan đến I / O, chuyển đổi ngữ cảnh, ...
shellholic

Câu trả lời:


18

Cách rõ ràng để giữ một loạt các tệp trong bộ đệm là truy cập chúng thường xuyên. Linux khá giỏi trong việc phân xử giữa hoán đổi và bộ nhớ đệm, vì vậy tôi nghi ngờ rằng sự khác biệt về tốc độ mà bạn quan sát được thực ra không phải do HĐH không giữ mọi thứ trong bộ đệm, mà do một số khác biệt khác giữa việc sử dụng tmpfs và các nỗ lực khác của bạn.

Hãy thử quan sát những gì đang làm IO trong từng trường hợp. Công cụ cơ bản cho điều đó là iotop. Các công cụ khác có thể hữu ích; xem phân tích tải IO của đĩa Linux, theo đường dẫn hệ thống tập tin và / hoặc quá trình? , Chương trình nào trong Linux có thể đo I / O theo thời gian? và các luồng khác tại Server Fault.

Dưới đây là một vài giả thuyết về những gì có thể xảy ra. Nếu bạn thực hiện các phép đo, vui lòng chỉ ra chúng để chúng tôi có thể xác nhận hoặc bác bỏ các giả thuyết này.

  • Nếu bạn có thời gian truy cập tệp được bật, HĐH có thể lãng phí khá nhiều thời gian để viết những lần truy cập này. Thời gian truy cập là vô ích đối với cây biên dịch, vì vậy hãy đảm bảo rằng chúng bị tắt với noatimetùy chọn gắn kết. Giải pháp tmpfs + rsync của bạn không bao giờ đọc từ đĩa cứng, vì vậy nó không bao giờ phải mất thêm thời gian để viết atimes.
  • Nếu ghi được đồng bộ hóa , do trình biên dịch gọi sync()hoặc do kernel thường xuyên xóa bộ đệm đầu ra của nó, việc ghi sẽ mất nhiều thời gian hơn vào đĩa cứng so với tmpfs.

Tôi cũng có cảm giác này. Biên dịch là CPU chuyên sâu, chứ không phải IO.
phunehehe

Hmmm, tôi muốn xem một bình luận từ @JaredC ở đây để xác nhận hoặc bác bỏ giả thuyết Gilles. 1,5 so với 5 phút là một sự khác biệt khá lớn ...
Daniel Alder

8

Linux theo mặc định sử dụng RAM làm bộ đệm đĩa. Như một minh chứng, hãy thử chạy time find /some/dir/containing/a/lot/of/files > /dev/nullhai lần, lần thứ hai nhanh hơn rất nhiều vì mọi nút in của đĩa được lưu trữ. Vấn đề ở đây là làm thế nào để sử dụng tính năng kernel này và ngăn chặn nỗ lực của bạn để thay thế nó.

Vấn đề là thay đổi swappiness. Hãy xem xét ba loại sử dụng bộ nhớ chính: chương trình hoạt động, chương trình không hoạt động và bộ đệm đĩa. Rõ ràng bộ nhớ được sử dụng bởi các chương trình hoạt động không nên bị tráo đổi và sự lựa chọn giữa hai người khác là khá tùy tiện. Bạn có muốn chuyển đổi chương trình nhanh hoặc truy cập tập tin nhanh? Một swappiness thấp thích giữ các chương trình trong bộ nhớ (thậm chí nếu không được sử dụng trong thời gian dài) và một swappiness cao thích giữ bộ nhớ cache đĩa hơn (bằng cách trao đổi các chương trình không sử dụng). (thang đo swappiness là từ 0 đến 100 và giá trị mặc định là 60)

Giải pháp của tôi cho vấn đề của bạn là thay đổi độ linh hoạt thành rất cao (90-95 không nói 100) và tải bộ đệm:

echo 95 | sudo tee /proc/sys/vm/swappiness > /dev/null # once after reboot
find /your/source/directory -type f -exec cat {} \; > /dev/null

Như bạn đoán, bạn phải có đủ bộ nhớ trống để lưu trong bộ đệm tất cả các tệp nguồn và tệp đối tượng cũng như trình biên dịch, bao gồm các tệp tiêu đề, thư viện được liên kết, IDE của bạn và các chương trình được sử dụng khác.


Điều này nói chung rất hữu ích, nhưng điều tôi thực sự muốn là mã nguồn của tôi có độ trao đổi thấp, nhưng mọi thứ khác đều có sự thay đổi bình thường. Về cơ bản, tôi có rất nhiều thứ đang diễn ra trong nền, nhưng tôi muốn giới hạn chúng ở mức 6 trên 8 GB, trong khi luôn giữ 2 GB còn lại cho mã nguồn. Tôi không muốn nhân cơ hội nó bị tráo đổi ... bao giờ ... bởi vì điều đó thật khó chịu.
JaredC

Swappiness là hệ thống rộng. Trong thực tế nếu bạn đang làm một cái gì đó khác và các tệp của bạn được tải khỏi bộ nhớ, bạn chỉ cần tải lại nó với dòng thứ hai. Nếu bộ nhớ phải được giải phóng cho một cái gì đó khác, bạn thực sự không "muốn nắm lấy cơ hội" nó sẽ được thực hiện từ trao đổi. BTW, tmpfstrong trường hợp tương tự cũng sẽ được hoán đổi.
shellholic

2
Cá nhân tôi đã giảm một swappiness cao là khủng khiếp trên máy trạm. Mặc dù một số chức năng có thể được tăng tốc bởi bộ đệm lớn hơn (tức là nhiều tệp được lưu trong bộ nhớ cache hơn) nhưng bạn phải trả giá cho điều này về khả năng đáp ứng khi chuyển đổi giữa các chương trình, đây là điều người dùng chú ý đầu tiên khi làm việc trên hệ thống. Khi chuyển từ trình duyệt này sang văn phòng khác sang một trình duyệt khác để gửi email, tôi không thể phải chờ 1-2 giây để mỗi chương trình trao đổi trở lại. Trên tất cả các máy linux của tôi, tôi thường đặt swappiness thành giá trị thấp 10.
fgysin phục hồi Monica

6

Buộc cache không phải là cách đúng đắn để làm điều này. Tốt hơn để giữ các nguồn trên ổ cứng và biên dịch chúng trên tmpfs. Nhiều hệ thống xây dựng, chẳng hạn như qmake và CMake, hỗ trợ các bản dựng ngoài nguồn.


6

Trình inosyncnền có vẻ như thực hiện chính xác những gì bạn muốn nếu bạn định rsync với ramdisk. Thay vì rsyncing cứ sau 10 giây hoặc lâu hơn, nó sử dụng cơ sở inotify của Linux để rsync khi một tệp thay đổi. Tôi đã tìm thấy nó trong kho Debian dưới dạng inosyncgói hoặc nguồn của nó có sẵn tại http://bb.xnull.de/projects/inosync/ .


Nghe có vẻ khá hữu ích. Tôi sẽ xem xét nó và báo cáo lại. Cảm ơn!
JaredC

5

Điều này dường như hoạt động với tôi nếu tôi muốn giữ một số tệp nhất định hoặc tất cả các tệp trong một thư mục nhất định trong bộ đệm.

vmtouch dường như chỉ làm điều đó. Ví dụ 5 có thể có những gì bạn cần.

vmtouch -dl /whatever/directory/

Tôi cần phải chạy nó với quyền root sudo


1
Nó không thấy các tập tin mới / bị loại bỏ.
Vi.

3

Cung cấp đủ bộ nhớ, bản dựng của bạn ra khỏi ramdisk không có I / O. Điều này có thể tăng tốc bất cứ điều gì đọc hoặc ghi tập tin. I / O là một trong những hoạt động chậm nhất. Ngay cả khi bạn nhận được mọi thứ được lưu trong bộ nhớ cache trước khi xây dựng, bạn vẫn có I / O để ghi, mặc dù chúng sẽ có tác động tối thiểu.

Bạn có thể nhận được một số tăng tốc bằng cách tải trước tất cả các tệp vào bộ đệm, nhưng thời gian thực hiện để được bao gồm trong tổng thời gian xây dựng. Điều này có thể không cung cấp cho bạn nhiều lợi thế.

Xây dựng các đối tượng và các tệp trung gian vào RAM chứ không phải đĩa. Thực hiện các bản dựng gia tăng có thể giúp bạn đạt được những thành tựu đáng kể trên các bản dựng thường xuyên. Trên hầu hết các dự án, tôi thực hiện xây dựng sạch hàng ngày và xây dựng gia tăng ở giữa. Các bản dựng tích hợp luôn là các bản dựng sạch, nhưng tôi cố gắng giới hạn chúng dưới một bản mỗi ngày.

Bạn có thể đạt được một số hiệu suất bằng cách sử dụng phân vùng ext2 khi tắt máy. Nguồn của bạn phải ở trong kiểm soát phiên bản trên một hệ thống tệp được ghi nhật ký như ext3 / 4.


2

Như đã nêu trước đây, cách rõ ràng là đọc tất cả các cấu trúc thư mục và nội dung tệp của những gì bạn muốn được lưu trữ.

Bạn có thể tự động hóa việc này bằng cách viết một tập lệnh để theo dõi đầu ra của vmstat 1(sử dụng bất kỳ công cụ tương đương nào cho HĐH của bạn) và giữ một tổng số khối được viết và đọc. Khi tổng vượt qua ngưỡng bạn chọn, hãy đọc tất cả các tệp bạn định lưu vào bộ đệm, đặt lại tổng, sau đó tiếp tục theo dõi đầu ra vmstat. Để đọc nhanh các tệp: nếu cây của bạn chứa nhiều tệp, hãy tránh find ... -exec cat, thay vào đó hãy thử find ... -print0 | xargs -0 cathoặc một chương trình tùy chỉnh sẽ không thực thi cat cho mỗi tệp.

Giám sát IO đĩa tốt hơn là sử dụng một khoảng thời gian cố định vì nó báo hiệu để đọc lại dữ liệu của bạn thường xuyên hơn hoặc ít hơn tùy thuộc vào tải IO của đĩa.

Tôi đã sử dụng phương pháp tự động này thành công trên các hệ thống mà tôi cần đọc một số tệp chỉ mục để luôn nhanh chóng, tránh I / O ổ cứng. Tôi cũng đã sử dụng strace để tạo danh sách mọi tệp được truy cập khi tôi đăng nhập để tôi có thể giữ mọi thứ nóng trong bộ nhớ cache để đăng nhập nhanh.

Đây có thể không phải là giải pháp tốt nhất có thể nhưng nó rất phù hợp với tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.