Paksa direktori untuk selalu berada dalam cache

35

Saya telah menguji berbagai metode untuk meningkatkan waktu yang dibutuhkan untuk mengkompilasi seluruh proyek c ++ saya. Saat ini dibutuhkan ~ 5 menit. Saya bereksperimen dengan distcc, ccache, dan lainnya. Baru-baru ini, saya menemukan bahwa jika saya menyalin seluruh proyek saya ke RAM-drive, dan kemudian mengkompilasi dari sana, itu memotong waktu kompilasi hingga 30% dari aslinya - hanya 1,5 menit.

Jelas, bekerja dari drive RAM tidak praktis. Jadi, apakah ada yang tahu cara saya bisa memaksa OS untuk selalu menyimpan direktori tertentu di-cache ? Saya masih ingin direktori untuk disinkronkan kembali ke disk seperti biasa, tetapi saya selalu ingin salinan data dalam memori juga. Apakah ini mungkin?

EDIT: Sebagai solusi yang memungkinkan, kami baru saja berpikir untuk meluncurkan daemon yang berjalan rsyncsetiap 10 detik atau lebih untuk menyinkronkan disk drive dengan drive RAM. Kemudian kami menjalankan kompilasi dari drive RAM. Ini rsyncsangat cepat, tetapi apakah ini benar-benar bekerja? Tentunya OS bisa berbuat lebih baik ....

JaredC
sumber
Cache bukan satu-satunya perbedaan antara tmpfs dan ext3 / 4; mereka memiliki penjurnalan, misalnya, yang akan ditulis terlepas dari caching.
André Paramés
1
Bisakah Anda timemengkompilasi dan membagikan hasilnya kepada kami? Itu akan menghilangkan beberapa kontroversi. make clean && /usr/bin/time -v make(jangan gunakan perintah bash built in time)
shellholic
1
@she Mengapa tidak perintah bawaan bash?
tshepang
3
@Tasukan timebuilt in bash ( help time) memiliki detail yang jauh lebih sedikit (tidak ada opsi verbose) daripada waktu GNU ( man time) mengenai I / O, switch konteks, ...
shellholic

Jawaban:

18

Cara yang jelas untuk menyimpan banyak file dalam cache adalah dengan sering mengaksesnya. Linux cukup bagus dalam arbitrase antara bertukar dan melakukan caching, jadi saya curiga perbedaan kecepatan yang Anda amati sebenarnya bukan karena OS tidak menyimpan hal-hal di cache, tetapi karena beberapa perbedaan lain antara penggunaan tmpfs dan upaya Anda lainnya.

Coba amati apa yang dilakukan IO dalam setiap kasus. Alat dasar untuk itu iotop. Alat-alat lain mungkin berguna; lihat disk Linux IO kerusakan, oleh jalur sistem file dan / atau proses?, Program apa di Linux yang dapat mengukur I / O dari waktu ke waktu? , dan utas lainnya di Server Fault.

Berikut adalah beberapa hipotesis tentang apa yang bisa terjadi. Jika Anda melakukan pengukuran, harap tunjukkan sehingga kami dapat mengkonfirmasi atau menyangkal hipotesis ini.

  • Jika waktu akses file Anda dihidupkan, OS mungkin membuang-buang waktu menulis waktu akses ini. Waktu akses tidak berguna untuk pohon kompilasi, jadi pastikan mereka dimatikan dengan noatimeopsi mount. Solusi tmpfs + rsync Anda tidak pernah membaca dari hard disk, sehingga tidak perlu menghabiskan waktu ekstra menulis atimes.
  • Jika penulisan menyinkronkan , baik karena kompilator memanggil sync()atau karena kernel sering mem-flush buffer outputnya, penulisan akan memakan waktu lebih lama untuk hard disk daripada ke tmpfs.
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya memiliki perasaan ini juga. Kompilasi lebih intensif dari pada CPU, bukan IO.
phunehehe
Hmmm, saya ingin melihat komentar dari @JaredC di sini mengkonfirmasi atau menolak hipotesis Gilles. 1,5 vs 5 tambang adalah perbedaan yang cukup besar ...
Daniel Alder
8

Linux secara default menggunakan RAM sebagai cache disk. Sebagai demonstrasi, coba jalankan time find /some/dir/containing/a/lot/of/files > /dev/nulldua kali, yang kedua kali jauh lebih cepat karena setiap inode disk di-cache. Intinya di sini adalah bagaimana memanfaatkan fitur kernel ini dan menghentikan upaya Anda untuk menggantinya.

Intinya adalah mengubah swappiness. Mari kita pertimbangkan tiga jenis utama penggunaan memori: program aktif, program tidak aktif dan cache disk. Jelas memori yang digunakan oleh program aktif tidak boleh ditukar dan pilihan antara dua lainnya cukup sewenang-wenang. Apakah Anda ingin perpindahan program cepat atau akses file cepat? Sebuah swappiness rendah lebih memilih untuk menjaga program dalam memori (bahkan jika tidak digunakan untuk waktu yang lama) dan swappiness tinggi lebih memilih untuk menjaga disk cache lebih (dengan menukar program yang tidak terpakai). (skala swappiness adalah 0 hingga 100 dan nilai default adalah 60)

Solusi saya untuk masalah Anda adalah mengubah swappiness menjadi sangat tinggi (90-95 bukan untuk mengatakan 100) dan memuat cache:

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

Saat Anda menebaknya, Anda harus memiliki cukup memori bebas untuk menyimpan semua file sumber dan file objek di cache, termasuk kompilator, termasuk file header, pustaka tertaut, IDE Anda, dan program lain yang digunakan.

shellholic
sumber
Ini berguna secara umum, tetapi yang benar-benar saya inginkan adalah kode sumber saya memiliki swappiness rendah, tetapi yang lainnya memiliki swappiness normal. Pada dasarnya, saya memiliki banyak hal yang terjadi di latar belakang, tetapi saya ingin membatasi mereka hingga 6 dari 8 GB, sambil selalu menyimpan 2 GB lainnya untuk kode sumber. Saya tidak ingin mengambil kesempatan itu ditukar ... pernah ... karena itu menjengkelkan.
JaredC
Swappiness adalah sistem yang luas. Bahkan jika Anda melakukan sesuatu yang lain dan file Anda dibongkar dari memori, Anda hanya perlu memuatnya kembali dengan baris kedua. Jika memori harus dibebaskan untuk sesuatu yang lain, Anda benar-benar tidak "ingin mengambil kesempatan" itu dilakukan dari swap. BTW, tmpfsdalam kasus yang sama juga akan ditukar.
shellholic
2
Secara pribadi saya jatuh swappiness tinggi yang jelas mengerikan di workstation. Meskipun beberapa fungsi mungkin dipercepat oleh cache yang lebih besar (yaitu lebih banyak file yang di-cache) ini ada harganya: Anda membayar untuk ini dalam hal responsif ketika beralih antar program, yang merupakan hal yang pertama kali diperhatikan pengguna saat bekerja pada suatu sistem. Ketika beralih dari browser ke kantor ke browser lain ke email, saya tidak bisa menunggu harus menunggu 1-2 detik untuk setiap program untuk bertukar kembali. Pada semua mesin linux saya, saya biasanya mengatur swappiness ke nilai rendah 10.
fgysin mengembalikan Monica
6

Memaksa cache bukan cara yang tepat untuk melakukan ini. Lebih baik menyimpan sumber di hard drive dan mengompilasinya di tmpfs. Banyak sistem build, seperti qmake dan CMake, mendukung build out-of-source.

gelraen
sumber
6

The inosyncsuara daemon seperti itu tidak persis apa yang Anda inginkan jika Anda akan rsync untuk ramdisk. Alih-alih rsyncing setiap 10 detik atau lebih, ia menggunakan fasilitas inotify Linux untuk rsync ketika file berubah. Saya menemukannya di repositori Debian sebagai inosyncpaket, atau sumbernya tersedia di http://bb.xnull.de/projects/inosync/ .

Jander
sumber
Kedengarannya sangat berguna. Saya akan memeriksanya dan melaporkan kembali. Terima kasih!
JaredC
5

Hal ini sepertinya berfungsi untuk saya jika saya ingin menyimpan file tertentu atau semua file dalam direktori tertentu dalam cache.

Vmtouch tampaknya melakukan hal itu. Contoh 5 mungkin ada yang Anda butuhkan.

vmtouch -dl /whatever/directory/

Saya perlu menjalankannya sebagai root sudo

Highstaker
sumber
1
Itu tidak melihat file baru / dihapus.
Vi.
3

Dengan memori yang cukup, build Anda dari ramdisk tidak menggunakan I / O. Ini dapat mempercepat apa pun yang membaca atau menulis file. I / O adalah salah satu operasi paling lambat. Bahkan jika Anda mendapatkan semuanya di-cache sebelum membangun Anda masih memiliki I / O untuk menulis, meskipun mereka harus memiliki dampak minimal.

Anda mungkin mendapatkan beberapa percepatan dengan memuat semua file ke dalam cache, tetapi waktu yang diperlukan untuk itu harus dimasukkan dalam total waktu pembuatan. Ini mungkin tidak memberi Anda banyak keuntungan.

Membangun objek dan file menengah ke dalam RAM daripada disk. Melakukan build tambahan mungkin memberi Anda keuntungan signifikan pada build sering. Pada sebagian besar proyek, saya melakukan pembangunan harian yang bersih dan pembangunan bertahap di antaranya. Membangun integrasi selalu membangun bersih, tetapi saya mencoba membatasi mereka menjadi kurang dari satu per hari.

Anda dapat memperoleh kinerja dengan menggunakan partisi ext2 dengan atime dimatikan. Sumber Anda harus dalam kontrol versi pada sistem file yang dijurnal seperti ext3 / 4.

BillThor
sumber
2

Seperti yang dinyatakan sebelumnya, cara yang jelas adalah membaca semua struktur direktori dan isi file dari apa yang ingin Anda cached.

Anda dapat mengotomatiskan ini dengan menulis skrip untuk memantau output vmstat 1(menggunakan alat apa pun yang setara untuk OS Anda) dan menyimpan jumlah blok yang ditulis dan dibaca. Setelah jumlah melewati ambang yang Anda pilih, baca semua file yang ingin Anda cache, setel ulang jumlahnya, kemudian lanjutkan memantau output vmstat. Untuk membaca file dengan cepat: jika pohon Anda berisi banyak file, hindari find ... -exec cat, sebaliknya cobalah find ... -print0 | xargs -0 catatau program khusus yang tidak akan menjalankan cat untuk setiap file.

Memantau disk IO lebih disukai daripada menggunakan interval tetap karena memberi sinyal untuk membaca ulang data Anda lebih atau kurang tergantung pada beban IO disk.

Saya telah menggunakan metode otomatis ini berhasil pada sistem di mana saya membutuhkan beberapa file indeks dibaca agar selalu cepat, menghindari I / O hard drive. Saya juga menggunakan strace untuk membuat daftar setiap file yang dapat diakses ketika saya masuk sehingga saya bisa menyimpan semuanya dalam cache untuk login cepat.

Ini mungkin bukan solusi terbaik tetapi cocok untuk saya.

filebar
sumber