Mencoba menjalankan program X menggunakan 8 utas dan selesai dalam n menit .
Mencoba menjalankan program yang sama menggunakan 50 utas dan selesai dalam n * 10 menit .
Mengapa ini terjadi dan bagaimana saya bisa mendapatkan jumlah utas optimal yang dapat saya gunakan?
multithreading
PoGibas
sumber
sumber
"Mengapa ini terjadi?" agak mudah dijawab. Bayangkan Anda memiliki koridor yang dapat memuat empat orang, berdampingan. Anda ingin memindahkan semua sampah di satu ujung, ke ujung lainnya. Jumlah orang yang paling efisien adalah 4.
Jika Anda memiliki 1-3 orang maka Anda kehilangan menggunakan beberapa ruang koridor. Jika Anda memiliki 5 orang atau lebih, maka setidaknya salah satu dari orang-orang itu pada dasarnya terjebak mengantri di belakang orang lain sepanjang waktu. Menambahkan semakin banyak orang hanya menyumbat koridor, itu tidak mempercepat aktivitas.
Jadi, Anda ingin memiliki sebanyak mungkin orang yang bisa masuk tanpa menyebabkan antrian. Mengapa Anda memiliki antrian (atau kemacetan) tergantung pada pertanyaan dalam jawaban slm.
sumber
4
adalah angka terbaik.Rekomendasi umum adalah n + 1 utas, n menjadi jumlah inti CPU yang tersedia. Dengan begitu n thread dapat bekerja pada CPU sementara 1 thread sedang menunggu disk I / O. Memiliki lebih sedikit utas tidak akan sepenuhnya memanfaatkan sumber daya CPU (pada titik tertentu akan selalu ada I / O untuk menunggu), memiliki lebih banyak utas akan menyebabkan utas memperebutkan sumber daya CPU.
Thread datang tidak gratis, tetapi dengan overhead seperti konteks switch, dan - jika data harus dipertukarkan antara thread yang biasanya terjadi - berbagai mekanisme penguncian. Ini hanya sepadan dengan biaya ketika Anda benar-benar memiliki inti CPU yang lebih berdedikasi untuk menjalankan kode. Pada CPU single core, proses tunggal (tanpa utas terpisah) biasanya lebih cepat daripada threading yang dilakukan. Utas tidak secara ajaib membuat CPU Anda lebih cepat, itu hanya berarti kerja ekstra.
sumber
Seperti yang telah ditunjukkan oleh orang lain ( jawaban slm , jawaban EightBitTony ) ini adalah pertanyaan yang rumit dan lebih lagi karena Anda tidak menggambarkan apa yang Anda lakukan dan bagaimana mereka melakukannya.
Tetapi secara definitif melemparkan lebih banyak utas dapat memperburuk keadaan.
Di bidang komputasi paralel ada hukum Amdahl yang dapat diterapkan (atau tidak bisa, tetapi Anda tidak menjelaskan detail masalah Anda, jadi ....) dan dapat memberikan wawasan umum tentang kelas masalah ini.
Inti hukum Amdahl adalah bahwa dalam program apa pun (dalam algoritma apa pun) selalu ada persentase yang tidak dapat dijalankan secara paralel (bagian berurutan ) dan ada persentase lain yang dapat dijalankan secara paralel (bagian paralel ) [Jelas dua bagian ini menambahkan hingga 100%].
Bagian ini dapat dinyatakan sebagai persentase dari waktu eksekusi. Sebagai contoh, bisa ada 25% waktu yang dihabiskan dalam operasi sekuensial ketat, dan 75% sisanya dihabiskan dalam operasi yang dapat dieksekusi secara paralel.
(Gambar dari Wikipedia )
Hukum Amdahl memperkirakan bahwa untuk setiap bagian paralel yang diberikan (misalnya 75%) dari suatu program Anda dapat mempercepat eksekusi sejauh ini (misalnya paling banyak 4 kali) bahkan jika Anda menggunakan lebih banyak prosesor untuk melakukan pekerjaan.
Sebagai aturan praktis, semakin banyak dari Anda memprogram yang tidak dapat Anda ubah dalam eksekusi paralel, semakin sedikit yang bisa Anda peroleh dengan menggunakan lebih banyak unit eksekusi (prosesor).
Mengingat Anda menggunakan utas (dan bukan prosesor fisik) situasinya bahkan bisa lebih buruk dari ini. Ingatlah bahwa utas dapat diproses (tergantung pada implementasi dan perangkat keras yang tersedia, mis. CPU / Cores) berbagi prosesor / inti fisik yang sama (ini adalah bentuk multitasking, seperti yang ditunjukkan dalam jawaban lain).
Prediksi teoretis ini (sekitar waktu CPU) tidak menganggap hambatan praktis lainnya sebagai
yang dapat dengan mudah menjadi faktor pembatas dalam aplikasi praktis.
sumber
Pelakunya di sini adalah "KONTEKS BERALIH". Ini adalah proses menyimpan status utas saat ini untuk mulai mengeksekusi utas lainnya. Jika sejumlah utas diberi prioritas yang sama, mereka harus dialihkan hingga mereka menyelesaikan eksekusi.
Dalam kasus Anda, ketika ada 50 utas, banyak pergantian konteks terjadi bila dibandingkan dengan hanya menjalankan 10 utas.
Overhead waktu ini diperkenalkan karena pengalihan konteks yang membuat program Anda berjalan lambat
sumber
ps ax | wc -l
melaporkan 225 proses, dan tidak berarti sangat dimuat). Saya cenderung untuk pergi dengan tebakan @ EightBitTony; cache cache kemungkinan masalah yang lebih besar, karena setiap kali Anda membersihkan cache, CPU harus menunggu ribuan tahun untuk kode dan data dari RAM.Untuk memperbaiki metafora EightBitTony:
Seseorang di sini adalah utas, dan ember mewakili sumber daya eksekusi mana pun yang menjadi penghambatnya. Menambahkan lebih banyak utas tidak membantu jika tidak bisa melakukan apa pun. Selain itu, kita harus menekankan bahwa mengoper ember dari satu orang ke orang lain biasanya lebih lambat daripada satu orang yang hanya membawa ember dengan jarak yang sama. Yaitu, dua utas secara bergantian pada inti biasanya menghasilkan lebih sedikit pekerjaan daripada satu utas yang berjalan dua kali lebih lama: ini karena kerja ekstra yang dilakukan untuk beralih di antara kedua utas.
Apakah sumber daya eksekusi terbatas (bucket) adalah CPU, atau inti, atau pipa instruksi hyper-threaded untuk tujuan Anda tergantung pada bagian arsitektur mana yang menjadi faktor pembatas Anda. Perhatikan juga kami mengasumsikan utas sepenuhnya independen. Ini hanya terjadi jika mereka tidak membagikan data (dan menghindari tabrakan cache apa pun).
Seperti yang disarankan oleh beberapa orang, untuk I / O sumber daya pembatas mungkin adalah jumlah operasi I / O yang dapat antri: ini dapat bergantung pada sejumlah faktor perangkat keras dan kernel, tetapi dapat dengan mudah jauh lebih besar dari jumlah core. Di sini, saklar konteks yang sangat mahal dibandingkan dengan kode eksekusi-terikat, cukup murah dibandingkan dengan kode terikat I / O. Sedihnya saya pikir metafora akan sepenuhnya di luar kendali jika saya mencoba untuk membenarkan ini dengan ember.
Perhatikan bahwa perilaku optimal dengan kode terikat I / O biasanya masih memiliki paling banyak satu utas per pipa / inti / CPU. Namun, Anda harus menulis kode I / O asinkron atau sinkron / non-pemblokiran, dan peningkatan kinerja yang relatif kecil tidak selalu membenarkan kompleksitas tambahan.
PS. Masalah saya dengan metafora koridor asli adalah sangat menyarankan Anda harus dapat memiliki 4 antrian orang, dengan 2 antrian membawa sampah dan 2 kembali untuk mengumpulkan lebih banyak. Kemudian Anda dapat membuat setiap antrian hampir sepanjang koridor, dan menambahkan orang melakukan mempercepat algoritma (Anda pada dasarnya mengubah seluruh koridor ke ban berjalan).
Sebenarnya skenario ini sangat mirip dengan deskripsi standar tentang hubungan antara latensi dan ukuran jendela dalam jaringan TCP, itulah sebabnya ia melompat ke arah saya.
sumber
Sangat mudah dan sederhana untuk dipahami. Memiliki lebih banyak utas daripada yang didukung CPU Anda, Anda benar-benar membuat serial dan tidak memparalelkan. Semakin banyak utas Anda, semakin lambat sistem Anda. Hasil Anda sebenarnya adalah bukti dari fenomena ini.
sumber