Katakanlah saya memiliki CPU 4-core, dan saya ingin menjalankan beberapa proses dalam jumlah waktu minimum. Prosesnya idealnya dapat diparalelkan, jadi saya bisa menjalankannya pada jumlah utas yang tak terbatas dan setiap utas membutuhkan jumlah waktu yang sama.
Karena saya memiliki 4 core, saya tidak mengharapkan adanya peningkatan dengan menjalankan lebih banyak thread daripada core, karena satu core hanya mampu menjalankan satu thread pada saat tertentu. Saya tidak tahu banyak tentang perangkat keras, jadi ini hanya tebakan.
Apakah ada manfaat untuk menjalankan proses yang dapat diparalelkan pada lebih banyak utas daripada inti? Dengan kata lain, apakah proses saya akan selesai lebih cepat, lebih lambat, atau dalam jumlah waktu yang sama jika saya menjalankannya menggunakan 4000 utas daripada 4 utas?
sumber
Saya setuju dengan jawaban @ Gonzalo. Saya memiliki proses yang tidak melakukan I / O, dan inilah yang saya temukan:
Perhatikan bahwa semua utas bekerja pada satu larik tetapi rentang yang berbeda (dua utas tidak mengakses indeks yang sama), sehingga hasilnya mungkin berbeda jika mereka bekerja pada larik yang berbeda.
Mesin 1,86 adalah udara macbook dengan SSD. Mac lainnya adalah iMac dengan HDD normal (saya pikir ini 7200 rpm). Mesin windows juga memiliki HDD 7200 rpm.
Dalam tes ini, jumlah optimal sama dengan jumlah inti dalam mesin.
sumber
Saya tahu pertanyaan ini agak lama, tetapi banyak hal telah berkembang sejak 2009.
Ada dua hal yang perlu diperhatikan sekarang: jumlah inti, dan jumlah utas yang dapat berjalan dalam setiap inti.
Dengan prosesor Intel, jumlah utas ditentukan oleh Hyperthreading yang hanya 2 (jika tersedia). Tapi Hyperthreading memangkas waktu eksekusi Anda menjadi dua, bahkan ketika tidak menggunakan 2 utas! (yaitu 1 pipa dibagi antara dua proses - ini bagus ketika Anda memiliki lebih banyak proses, tidak begitu baik sebaliknya. Lebih banyak core secara definitif lebih baik!)
Pada prosesor lain, Anda mungkin memiliki 2, 4, atau bahkan 8 utas. Jadi, jika Anda memiliki 8 core yang masing-masing mendukung 8 thread, Anda bisa membuat 64 proses berjalan secara paralel tanpa pengalihan konteks.
"Tanpa pengalihan konteks" jelas tidak benar jika Anda menjalankan dengan sistem operasi standar yang akan melakukan pengalihan konteks untuk semua hal lain di luar kendali Anda. Tapi itu ide utamanya. Beberapa OS memungkinkan Anda mengalokasikan prosesor sehingga hanya aplikasi Anda yang memiliki akses / penggunaan prosesor tersebut!
Dari pengalaman saya sendiri, jika Anda memiliki banyak I / O, banyak utas baik. Jika Anda memiliki pekerjaan yang sangat berat memori (baca sumber 1, baca sumber 2, perhitungan cepat, tulis) maka memiliki lebih banyak utas tidak membantu. Sekali lagi, ini tergantung pada seberapa banyak data yang Anda baca / tulis secara bersamaan (yaitu jika Anda menggunakan SSE 4.2 dan membaca nilai 256 bit, yang menghentikan semua utas dalam langkah mereka ... dengan kata lain, 1 utas mungkin jauh lebih mudah untuk diterapkan dan mungkin hampir secepat jika tidak benar-benar lebih cepat. Ini akan tergantung pada proses & arsitektur memori Anda, beberapa server canggih mengelola rentang memori yang terpisah untuk core terpisah sehingga utas terpisah akan lebih cepat dengan asumsi data Anda diajukan dengan benar ... itulah sebabnya, pada beberapa arsitektur, 4 proses akan berjalan lebih cepat dari 1 proses dengan 4 utas.)
sumber
Kinerja aktual akan tergantung pada seberapa banyak hasil sukarela dari setiap utas akan dilakukan. Misalnya, jika utas sama sekali TIDAK I / O dan tidak menggunakan layanan sistem (yaitu 100% terikat CPU) maka 1 utas per inti adalah yang optimal. Jika utas melakukan sesuatu yang membutuhkan penantian, maka Anda harus bereksperimen untuk menentukan jumlah utas optimal. 4000 utas akan menimbulkan penjadwalan overhead yang signifikan, jadi itu mungkin juga tidak optimal.
sumber
Jawabannya tergantung pada kompleksitas algoritma yang digunakan dalam program. Saya datang dengan metode untuk menghitung jumlah optimal thread dengan membuat dua pengukuran waktu pemrosesan Tn dan Tm untuk dua jumlah sewenang-wenang thread 'n' dan 'm'. Untuk algoritma linier, jumlah utas optimal adalah N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).
Silakan baca artikel saya mengenai perhitungan angka optimal untuk berbagai algoritma: pavelkazenin.wordpress.com
sumber
Saya pikir saya akan menambahkan perspektif lain di sini. Jawabannya tergantung pada apakah pertanyaannya mengasumsikan skala lemah atau skala kuat.
Dari Wikipedia :
Penskalaan lemah: perbedaan waktu solusi dengan jumlah prosesor untuk ukuran masalah yang diperbaiki per prosesor.
Skala yang kuat: bagaimana waktu solusi bervariasi dengan jumlah prosesor untuk ukuran masalah total yang tetap.
Jika pertanyaannya dengan asumsi skala lemah maka jawaban @ Gonzalo sudah cukup. Namun jika pertanyaannya adalah asumsi skala yang kuat, ada sesuatu yang lebih untuk ditambahkan. Dalam penskalaan yang kuat, Anda mengasumsikan ukuran beban kerja tetap jadi jika Anda menambah jumlah utas, ukuran data yang dibutuhkan setiap utas untuk bekerja berkurang. Pada CPU modern, akses memori mahal dan akan lebih baik untuk mempertahankan lokalitas dengan menyimpan data dalam cache. Oleh karena itu, jumlah utas yang optimal yang mungkin dapat ditemukan ketika set data dari setiap utas cocok dengan cache masing-masing inti (saya tidak akan membahas rincian membahas apakah itu cache L1 / L2 / L3 dari sistem).
Ini berlaku bahkan ketika jumlah utas melebihi jumlah inti. Sebagai contoh, asumsikan ada 8 unit sewenang-wenang (atau AU) pekerjaan dalam program yang akan dieksekusi pada mesin 4 inti.
Kasus 1: jalankan dengan empat utas di mana setiap utas perlu menyelesaikan 2AU. Setiap utas membutuhkan waktu 10 detik untuk menyelesaikan ( dengan banyak cache yang hilang ). Dengan empat core, jumlah total waktu adalah 10 detik (10 detik * 4 utas / 4 core).
Kasus 2: jalankan dengan delapan utas di mana setiap utas perlu menyelesaikan 1AU. Setiap utas hanya membutuhkan 2s (bukan 5s karena berkurangnya jumlah cache yang hilang ). Dengan empat core, jumlah total waktu adalah 4s (2s * 8 threads / 4 core).
Saya telah menyederhanakan masalah dan mengabaikan biaya overhead yang disebutkan dalam jawaban lain (mis., Sakelar konteks) tetapi harap Anda mengerti bahwa mungkin bermanfaat untuk memiliki jumlah utas lebih banyak daripada jumlah inti yang tersedia, tergantung pada ukuran data Anda. sedang berurusan dengan.
sumber
4000 utas sekaligus cukup tinggi.
Jawabannya adalah ya dan tidak. Jika Anda melakukan banyak pemblokiran I / O di setiap utas, maka ya, Anda bisa menunjukkan peningkatan yang signifikan hingga mungkin 3 atau 4 utas per inti logis.
Namun, jika Anda tidak melakukan banyak hal yang menghalangi, maka overhead tambahan dengan threading hanya akan membuatnya lebih lambat. Jadi gunakan profiler dan lihat di mana kemacetan di setiap bagian yang mungkin paralel. Jika Anda melakukan perhitungan yang berat, maka lebih dari 1 utas per CPU tidak akan membantu. Jika Anda melakukan banyak transfer memori, itu tidak akan membantu. Jika Anda melakukan banyak I / O meskipun seperti untuk akses disk atau akses internet, maka ya beberapa utas akan membantu hingga batas tertentu, atau setidaknya membuat aplikasi lebih responsif.
sumber
Tolok ukur.
Saya akan mulai meningkatkan jumlah utas untuk suatu aplikasi, mulai dari 1, dan kemudian menuju ke sesuatu seperti 100, menjalankan tiga-lima percobaan untuk setiap jumlah utas, dan membuat sendiri grafik kecepatan operasi vs jumlah utas .
Anda harus memastikan bahwa kasing empat optimal, dengan sedikit kenaikan pada runtime setelah itu, tetapi mungkin tidak. Mungkin saja aplikasi Anda dibatasi bandwidth, yaitu dataset yang Anda muat ke memori sangat besar, Anda mendapatkan banyak cache yang terlewat, dll., Sehingga 2 utas optimal.
Anda tidak bisa tahu sampai Anda menguji.
sumber
Anda akan menemukan berapa banyak utas yang dapat Anda jalankan di mesin Anda dengan menjalankan perintah htop atau ps yang mengembalikan jumlah proses pada mesin Anda.
Anda dapat menggunakan halaman manual tentang perintah 'ps'.
Jika Anda ingin menghitung jumlah semua proses pengguna, Anda dapat menggunakan salah satu dari perintah ini:
ps -aux| wc -l
ps -eLf | wc -l
Menghitung jumlah proses pengguna:
ps --User root | wc -l
Anda juga dapat menggunakan "htop" [Referensi] :
Menginstal di Ubuntu atau Debian:
Menginstal di Redhat atau CentOS:
Jika Anda ingin mengkompilasi htop dari kode sumber, Anda akan menemukannya di sini .
sumber
Idealnya adalah 1 utas per inti, asalkan tidak ada utas yang akan diblokir.
Satu kasus di mana hal ini mungkin tidak benar: ada utas lain yang berjalan pada inti, dalam hal ini lebih banyak utas mungkin memberi program Anda irisan waktu eksekusi yang lebih besar.
sumber
Salah satu contoh dari banyak utas ("kumpulan benang") vs satu per inti adalah penerapan server web di Linux atau Windows.
Karena soket disurvei di Linux, banyak utas dapat meningkatkan kemungkinan salah satu dari mereka memilih soket yang tepat pada waktu yang tepat - tetapi biaya pemrosesan keseluruhan akan sangat tinggi.
Di Windows, server akan diimplementasikan menggunakan I / O Completion Ports - IOCPs - yang akan membuat aplikasi didorong oleh peristiwa: jika I / O menyelesaikan OS, meluncurkan thread siaga untuk memprosesnya. Ketika pemrosesan telah selesai (biasanya dengan operasi I / O lainnya seperti pada pasangan permintaan-respons) utas kembali ke port IOCP (antrian) untuk menunggu penyelesaian selanjutnya.
Jika tidak ada I / O yang selesai, tidak ada pemrosesan yang harus dilakukan dan tidak ada utas yang diluncurkan.
Memang, Microsoft merekomendasikan tidak lebih dari satu utas per inti dalam implementasi IOCP. I / O apa pun dapat dilampirkan pada mekanisme IOCP. IOC juga dapat diposting oleh aplikasi, jika perlu.
sumber
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
berbicara dari sudut pandang komputasi dan memori (komputasi ilmiah) 4000 thread akan membuat aplikasi berjalan sangat lambat. Bagian dari masalah adalah overhead konteks switching yang sangat tinggi dan kemungkinan besar memori lokalitas yang sangat buruk.
Tetapi itu juga tergantung pada arsitektur Anda. Dari tempat saya mendengar prosesor Niagara seharusnya dapat menangani beberapa utas pada inti tunggal menggunakan semacam teknik perpipaan tingkat lanjut. Namun saya tidak punya pengalaman dengan prosesor tersebut.
sumber
Semoga ini masuk akal, Periksa penggunaan CPU dan Memori dan berikan nilai ambang batas. Jika nilai ambang dilewati, jangan izinkan untuk membuat utas baru lagi, izinkan ...
sumber