Apakah utas menggunakan memori virtual atau memori nyata?

10

Saya mencoba untuk mengoptimalkan server Linux saya untuk menangani 10.000 utas per proses sementara itu hanya 382 saat ini. Sesuai artikel ini , rumus berikut digunakan untuk mengetahui jumlah utas yang mungkin:

number of threads = total virtual memory / (stack size*1024*1024)

Ini berarti utas menyimpan semua datanya dalam memori virtual. Dan sejauh pengetahuan saya, memori virtual adalah ruang swap di mesin Linux yang disimpan pada harddisk daripada RAM atau cache.

Jadi pertanyaan saya adalah apakah utas kami menggunakan harddisk untuk menyimpan untuk memproses / menyimpan datanya.

Jika ya, bukankah ini mempengaruhi kinerja? Bisakah kita meningkatkan kinerja dengan memasukkannya ke dalam RAM atau cache? Bagaimana?

Jika tidak, bagaimana tepatnya cara kerja thread?

Memperbarui:

Menurut jawaban useless , memori virtual adalah sistem yang terdiri dari kira-kira:

  • memori fisik (RAM)
  • setiap swapfile yang telah Anda lampirkan
  • dukungan perangkat keras untuk menerjemahkan virtual ke alamat fisik dan mengeluarkan kesalahan halaman ketika alamat virtual tidak tersedia dalam memori fisik
  • dukungan perangkat lunak (kernel) untuk: mengelola tabel pencarian yang digunakan oleh perangkat keras yang menangani kesalahan halaman dengan menarik halaman dari swap saat diminta

Dengan demikian, Segala sesuatu yang ada di memori virtual secara kolektif pada RAM (Memori Nyata) dan Hard Disk (File Swap). Dan seperti yang dijelaskan James dalam keputusan jawabannya tentang Ram vs HDD diambil oleh Kernel menggunakan algoritma seperti LRU.

dragosrsupercool
sumber
2
kecuali server Anda memiliki 10.000 CPU / Core Anda membuang-buang waktu Anda.
@JarrodRoberson: Apa alasannya?
dragosrsupercool
3
10.000 utas bukan cara yang baik untuk membuat hal-hal berskala, itu adalah cara yang baik untuk membuat server merangkak, lebih dari 1 utas per CPU atau Core hanya akan membuat konteks server beralih dan berjalan lebih lambat tidak lebih cepat.
Khususnya, ketika Anda mengatakan "mencoba mengoptimalkan server Linux saya" - apa yang ingin Anda optimalkan? Jika ini throughput, maka satu utas per CPU dengan I / O multiplexing dan non-blocking cenderung lebih baik.
berguna

Jawaban:

12

sepengetahuan saya, memori virtual adalah ruang swap di mesin Linux

Tidak, memori virtual adalah sistem yang terdiri dari kira-kira:

  • memori fisik (RAM)
  • setiap swapfile yang telah Anda lampirkan
  • dukungan perangkat keras untuk menerjemahkan virtual ke alamat fisik dan mengeluarkan kesalahan halaman ketika alamat virtual tidak tersedia dalam memori fisik
  • dukungan perangkat lunak (kernel) untuk:
    • mengelola tabel pencarian yang digunakan oleh perangkat keras itu
    • menangani kesalahan halaman tersebut dengan menarik halaman dari swap saat diminta

Terserah kernel untuk memastikan memori virtual yang Anda inginkan di-cache ke RAM ketika Anda menginginkannya - kecuali Anda sedang menulis lapisan VM userspace Anda sendiri (seperti yang sering dilakukan oleh database, iiuc), jangan khawatir tentang hal itu.

Tak berguna
sumber
Ok jadi anggapan memori virtual saya salah. Pokoknya pertanyaan tindak lanjut cepat .. Apakah kinerja thread maksimal akan terpengaruh jika SWAP Space lebih dari RAM?
dragosrsupercool
@dragosrsupercool: ruang swap Anda akan selalu lebih besar dari memori fisik, jika tidak ada kebutuhan untuk menggunakan memori virtual.
Bryan Oakley
1
@BryanOakley: Itu belum tentu benar. Beberapa OS mengalokasikan halaman swap untuk setiap halaman virtual yang dialokasikan (mis. Swap harus setidaknya sama besar dengan fisik). OS lain mengalokasikan halaman swap hanya ketika ada kebutuhan untuk memindahkan halaman dari memori fisik (mis. Swap mungkin kurang dari fisik). Keuntungan dari yang pertama adalah bahwa jika alokasi berhasil, maka menukar memori itu selalu berhasil. Keuntungan dari yang terakhir adalah Anda tidak perlu secara pesimis mengalokasikan file swap besar untuk memperhitungkan situasi yang relatif jarang terjadi.
mcmcc
1
@dragosrsupercool, kinerja tidak akan terpengaruh oleh jumlah RAM, swap atau rasio di antara mereka kecuali Anda kekurangan RAM dan benar-benar paging. sar dapat memberi tahu Anda tentang aktivitas paging iirc (dicentang: sar -Bdi Linux).
Tak berguna
@Useless: Saya ingin menambah jumlah utas sampai saya sepenuhnya menggunakan RAM dan tidak mulai membuka halaman.
dragosrsupercool
14

Jika utas benar-benar berjalan maka instruksi saat ini, dan, variabel apa pun yang digunakan utas harus dalam memori fisik.

Sebagian besar (sebenarnya hampir semua) program berada di memori virtual, dan, sebagian besar program menggunakan memori virtual untuk penyimpanan variabel.

Alamat virtual disusun dalam potongan yang disebut halaman (ini biasanya 4.096 atau blok 8192 byte).

Pada waktu tertentu setiap blok memori virtual disimpan di suatu tempat di memori nyata atau di disk di "ruang swap" yang disediakan untuk ini.

Kode program Anda berhubungan dengan alamat virtual, ketika Anda bercabang ke alamat virtual, atau, meminta akses ke penyimpanan di alamat virtual sistem (biasanya di tingkat perangkat keras) menemukan lokasi saat ini dari permintaan alamat dan memetakannya ke alamat virtual Anda, jika alamat saat ini berada di disk, halaman itu menjadi memori nyata dan kemudian memetakan alamat.

Jelas ketika semua memori fisik sedang digunakan jika ada sesuatu yang di-paging maka sesuatu yang lain harus dikeluarkan, sehingga sistem mencari halaman "Paling Baru Digunakan" dan menyalinnya ke disk sebelum menyalin halaman yang Anda minta masuk.

Dalam sistem modern ada beberapa optimasi dan trik yang terkait dengan penyimpanan virtual.

  • Alamat dipetakan berdasarkan "per proses" jadi misalnya semua program C dalam kotak Linux memulai proses "utama" di alamat yang sama.
  • Ini dapat memungkinkan beberapa proses 32 bit untuk menempati dan menggunakan lebih dari 4GB pada mesin karena alamat virtual 32 bit dapat dipetakan ke alamat 64 bit yang sebenarnya.
  • Ketika proses berakhir atau memori dinyatakan "bebas", sistem hanya menandai halaman sebagai bebas, mereka tidak pernah disalin kembali ke disk swap.
  • Demikian pula ketika blok penyimpanan baru diminta, sistem hanya mengambil halaman gratis di memori nyata, tidak, IO disk terjadi.
  • Fungsi sleep dan hibernate memaksa semua memori untuk disalin ke ruang swap sehingga semua proses saat ini dan di sana konten memori saat ini dapat diciptakan kembali saat bangun.
James Anderson
sumber
3
"Semua program C dalam kotak Linux memulai [utama] pada alamat yang sama" tampaknya tidak memperhitungkan pengacakan tata letak ruang alamat. Itu semakin banyak digunakan hari ini untuk menggagalkan berbagai skema serangan smashing stack. Jawaban yang bagus sebaliknya, jadi +1.
CVn
7

Pertama-tama, Anda perlu membaca lebih lanjut tentang memori komputer , karena Anda tampaknya tidak memiliki pengetahuan di bidang itu.

Utas eksekusi adalah unit pemrosesan terkecil yang dapat dijadwalkan oleh sistem operasi. Implementasi thread dan proses berbeda dari satu sistem operasi ke yang lain, tetapi dalam kebanyakan kasus, sebuah thread terkandung di dalam suatu proses. Beberapa utas dapat ada dalam proses yang sama dan berbagi sumber daya seperti memori, sementara proses yang berbeda tidak membagikan sumber daya ini.

Jadi, utas akan menggunakan memori yang tersedia - apa pun jenisnya yang tersedia. Berapa banyak utas yang dapat Anda mulai tergantung pada ukuran memori dan berapa banyak memori yang dibutuhkan per utas. Jika utas menggunakan tumpukan (tidak hanya tumpukan), maka itu membutuhkan lebih banyak memori, dan dalam hal ini Anda dapat memulai lebih sedikit utas.

BЈовић
sumber
@VJonvic: +1 untuk penjelasan utas dasar.
dragosrsupercool
6

Jawaban sederhana untuk pertanyaan Anda adalah, mereka menggunakan memori virtual. semuanya menggunakan memori virtual kecuali beberapa proses yang terkait dengan OS.

Di sisi lain, ketika utas Anda (atau utas apa pun, dalam proses apa pun) benar-benar berjalan, ia menggunakan memori fisik. Halaman memori yang terkait dengan proses itu ditukar dengan memori fisik yang merupakan tempat prosesor melakukan fungsinya.

Bryan Oakley
sumber
3

Memori virtual adalah RAM Anda ditambah ruang swap Anda. Virtual hanya berarti alamat yang dilihat oleh program Anda berbeda dari alamat yang dilihat oleh chip RAM. Jika Anda perlu mengakses memori dalam swap, OS akan memindahkannya ke RAM terlebih dahulu. Jika Anda tidak ingin pertukaran, matikan saja. Jika Anda memiliki cukup RAM, Anda tidak benar-benar membutuhkannya.

Yang sedang berkata, kecuali Anda memiliki prosesor 10.000 inti, meningkatkan menjadi 10.000 utas bukan benar-benar sebuah "optimasi." Setelah Anda memiliki cukup utas untuk mengkonsumsi semua inti, ditambah satu atau dua cadangan untuk saat utas tersebut diblokir, menambahkan lebih banyak utas mengurangi kinerja karena overhead pergantian dan cache gagal. Anda mungkin masih ingin menggunakan lebih banyak utas jika itu membuat logika program Anda lebih sederhana, tetapi Anda akan memperdagangkan kinerja.

Karl Bielefeldt
sumber
Ya, 10.000 terlalu banyak karena server saya adalah mesin single core 32bit. Sebenarnya, utas bukan hal total cpu. Mereka adalah utas perayap, sehingga terkadang mereka seperti menunggu respons server. Saya bertujuan untuk memastikan cpu benar-benar sibuk tetapi tidak kelebihan atau kekurangan. Tetapi saya masih gagal memahami bagaimana saya bisa tahu apakah CPU itu gratis atau benar-benar sibuk. Apakah ada alat atau perintah?
dragosrsupercool
Saya pikir Anda bisa mendapatkan informasi itu dari topperintah.
Karl Bielefeldt
@KarlBieledeldt: ya itu persis apa yang saya cari .. Satu lagi pertanyaan lanjutan: Saya baru saja datang dengan ide untuk merangkak bahwa jika beberapa bagaimana satu utas dapat mengirim permintaan untuk url sementara utas lainnya menerima respons server maka saya dapat menyimpannya Pemanfaatan CPU tinggi tanpa menggunakan terlalu banyak utas. Apakah itu mungkin? Suka mengirim permintaan dari satu utas saat menerima respons di utas lainnya?
dragosrsupercool
2

optimalkan server Linux saya untuk menangani 10.000 utas per proses

Seperti yang dijelaskan orang lain, ini umumnya salah. Sebuah benang adalah sumber daya mahal , terutama karena memiliki sendiri panggilan stack (biasanya, megabyte) dan karena itu adalah tugas schedulable oleh kernel. Utas bahkan lebih mahal daripada deskriptor file yang dibuka .

Baca Sistem Operasi: Tiga Potong Mudah (buku teks yang dapat diunduh secara bebas)

Sebagai aturan praktis, Anda tidak ingin memiliki banyak utas, dan tentu saja tidak banyak utas yang dapat dijalankan. Jumlah utas runnable umumnya harus paling banyak jumlah inti (atau kelipatan kecil dari itu), jadi sekitar selusin paling banyak. Jumlah utas dalam suatu proses bisa sedikit lebih besar. Jadi kecuali Anda memiliki server yang sangat luas (dengan banyak soket dan inti prosesor), Anda tidak ingin memiliki lebih dari selusin utas yang dapat dijalankan, dan seratus utas (kebanyakan dari mereka tidak digunakan) dalam proses Anda (pada desktop Anda) .

Di Linux, utas dan proses sangat mirip (karena keduanya dapat dibuat oleh klon (2) ) dan keduanya adalah tugas yang dijadwalkan oleh kernel. Sebenarnya penjadwal kernel adalah tugas penjadwalan yang dapat berupa utas di dalam beberapa proses multi-utas, atau utas utama tunggal dari proses utas tunggal (dalam hal ini, Anda akan menamai "proses" dengan utas tunggal), atau utas kernel. Anda mungkin tidak ingin memiliki lebih dari seribu tugas yang dapat dijadwalkan secara total pada sistem desktop Anda.

Di Linux, suatu proses hanyalah sekelompok utas yang berbagi ruang alamat virtual yang sama (dan berbagi beberapa hal lain, seperti tabel deskriptor file, dll ...). Beberapa proses hanya memiliki satu utas.

Sebuah ruang alamat virtual yang didefinisikan oleh Wikipedia sebagai

"set kisaran alamat virtual yang disediakan sistem operasi untuk suatu proses"

(tetapi lihat juga jawaban ini yang menjelaskan bahwa terminologinya tidak universal, dan beberapa dokumentasi Microsoft menggunakan definisi yang berbeda dan tidak sesuai ).

Di Linux, proc (5) berguna untuk memahami ruang alamat virtual dari beberapa proses. Coba keduanya
cat /proc/self/mapsdan cat /proc/$$/mapsdi terminal. Lihat juga ini , dan pmap (1) & ps (1) & top (1) .

Semua program ruang pengguna berjalan dalam beberapa proses dan menggunakan memori virtual sehingga setiap proses memiliki ruang alamat virtual sendiri. RAM fisik adalah sumber daya yang dikelola oleh kernel Linux, dan aplikasi tidak memiliki akses langsung ke RAM (kecuali oleh mmap (2) -ing /dev/mem, lihat mem (4) ).

Jadi suatu proses tidak menggunakan RAM secara langsung . Ini menggunakan memori virtual dan memiliki ruang alamat virtual sendiri. The kernel menggunakan paging untuk mengelola RAM fisik halaman dan memberikan ruang alamat virtual dan proses abstraksi . Kapan saja (bahkan ketika proses Anda idle, atau ketika sedang berjalan) kernel bisa mengeluarkan beberapa halaman (misalnya menukar mereka pada disk). Kernel mengkonfigurasi MMU (dan menangani pengecualian perangkat keras kehilangan halaman dalam beberapa interrupt handler , baik dengan mengambil halaman dari disk atau dengan menyebarkan kesalahan segmentasi ke proses, lihat sinyal (7) )

Anda dapat memiliki utas hijau di atas utas sistem (tapi pustaka utas hijau sulit diterapkan dan didebug). Lihatlah goroutine yang digunakan di Go untuk contoh yang bagus. Lihat juga setcontext (3) .

Terkadang, sistem Anda dapat bereksperimen meronta-ronta . Ini terjadi ketika total memori virtual (dibutuhkan oleh semua proses) melebihi -dengan faktor besar- RAM fisik yang tersedia. Kemudian komputer Anda menjadi tidak responsif. Baca tentang ukuran set penduduk , paging permintaan , set kerja , overcommitmment memori , ASLR .

Lihat juga -untuk Linux- fork (2) , clone (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , kredensial (7) , pthreads (7) , futex (7) , kemampuan (7) .

Basile Starynkevitch
sumber