Jumlah optimal utas per inti

281

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?

Juliet
sumber

Jawaban:

254

Jika utas Anda tidak melakukan I / O, sinkronisasi, dll., Dan tidak ada yang lain yang berjalan, 1 utas per inti akan memberi Anda kinerja terbaik. Namun itu sangat tidak mungkin terjadi. Menambahkan lebih banyak utas biasanya membantu, tetapi setelah beberapa titik, mereka menyebabkan penurunan kinerja.

Belum lama ini, saya melakukan pengujian kinerja pada mesin 2 quad-core yang menjalankan aplikasi ASP.NET di Mono di bawah beban yang cukup baik. Kami bermain dengan jumlah minimum dan maksimum utas dan pada akhirnya kami menemukan bahwa untuk aplikasi tertentu dalam konfigurasi tertentu, throughput terbaik ada di antara 36 dan 40 utas. Apa pun di luar batas itu berkinerja lebih buruk. Pelajaran yang dipetik? Jika saya jadi Anda, saya akan menguji dengan jumlah utas yang berbeda sampai Anda menemukan nomor yang tepat untuk aplikasi Anda.

Satu hal yang pasti: 4k utas akan lebih lama. Itu banyak konteks switch.

Gonzalo
sumber
21
Saya pikir jawaban Gonzalo baik. Saya hanya menambahkan bahwa Anda harus bereksperimen dan mengukur. Program Anda akan berbeda dari miliknya, atau milik saya, atau orang lain dan hanya pengukuran perilaku program Anda sendiri yang akan menjawab pertanyaan Anda dengan benar. Kinerja program paralel (atau konkuren) bukan bidang di mana kesimpulan yang baik dapat diambil dari prinsip pertama saja.
High Performance Mark
5
+1, + jawaban: mengejutkan saya bahwa memiliki lebih banyak utas daripada inti menghasilkan kinerja yang lebih baik, meskipun masuk akal jika lebih banyak utas berarti lebih banyak waktu dibandingkan dengan utas yang bersaing. Alangkah baiknya aplikasi saya dapat mendeteksi perbedaan dalam kinerja dan secara otomatis menyesuaikan diri dengan jumlah utas yang optimal.
Juliet
12
Seharusnya tidak mengejutkan Anda dalam skenario dunia nyata. Blok thread menunggu sumber daya IO seperti akses disk, jaringan, dll. Dan juga menunggu sumber daya non IO seperti utas lainnya selesai menggunakan variabel yang dibagi. Apa yang benar-benar ingin Anda capai adalah jumlah minimum utas sehingga setidaknya satu utas per inti selalu dapat berjalan.
patros
4
1 utas per inti bukan yang optimal. Perlu sedikit lebih, lebih disukai dua kali karena ini akan memungkinkan utas lain berjalan jika utas sementara diblokir. Kalaupun hanya ada di memori. Ini lebih penting jika Anda memiliki sistem (P4, I7, Sun Rock dll) yang menampilkan SMT / HT)
Marco van de Voort
1
Oleh karena itu, "Itu sangat tidak mungkin terjadi" dalam jawaban saya. Menemukan nomor yang tepat tergantung pada aplikasi dan arsitektur yang digunakan.
Gonzalo
129

Saya setuju dengan jawaban @ Gonzalo. Saya memiliki proses yang tidak melakukan I / O, dan inilah yang saya temukan:

masukkan deskripsi gambar di sini

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.

Motasim
sumber
14
+1 untuk grafik. Jelas 1 utas per inti adalah yang terbaik, tetapi menarik bahwa sistem quad core tampaknya tidak pada nomor utas yang lebih tinggi (<100 pula) seperti yang dilakukan orang lain.
Jim Garrison
46
-1 untuk grafik! Kurva yang halus melalui koordinat x bernilai integer? Lompatan liar dari 1 2 3 hingga 10 20 30 hingga 50 100? Dan koordinat y yang merupakan kelipatan dari 10 ditambah 2 untuk ukuran yang baik. Ini yang dilakukan Excel, bukan?
Spacedman
5
@Spacedman Ya itu. Kurva yang halus memiliki tampilan IMHO yang jauh lebih baik. : D
Motasim
22
@ Pascalvootoot, Masalahnya bukan itu terlihat cantik, itu menipu pada pandangan pertama. Pertama-tama sumbu y dimulai pada 42, melebih-lebihkan perbedaan yang tampak antara mesin yang diuji. Kedua, perkembangan aneh dari nilai sumbu x menunjukkan bahwa 'waktu yang diambil' tidak skala secara linear dengan 'jumlah utas', ini terutama berlaku untuk garis biru. Saya pikir masalah yang orang lain (termasuk saya) miliki adalah bahwa ia salah mengartikan data.
pauluss86
13
@Spacedman Kritik pada grafik adalah hal paling konyol yang saya temui dalam 24 jam terakhir. Grafik membantu. Banyak. Titik. Mungkinkah itu dilakukan lebih baik? Tidak ada yang peduli. Kurva yang halus bukannya terpisah? Itu masalahmu ???? Saya berasumsi, Anda semua tidak akan pernah memasukkan grafik seperti itu ke dalam jawaban mereka karena Anda tidak memiliki waktu / energi ekstra untuk membuatnya terlihat bagus. Itu poin saya.
tyrex
50

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.)

Alexis Wilke
sumber
4
Mungkin ada yang lain, tapi yang saya tahu adalah prosesor POWER dari IBM. Mereka memiliki sistem dengan 4 atau 8 utas per prosesor. Sekarang mereka dapat memutar lebih banyak inti, sehingga mereka menawarkan 2 utas per inti sebagai gantinya ...
Alexis Wilke
Ini sudah tua, tetapi sebagian besar Intel i5, i7 memiliki cpu multi-threads seperti misalnya cpu i7 biasanya memiliki 4 core, tetapi 8 thread.
Edgar.
4
Prosesor tidak memiliki utas. Mereka memiliki inti fisik dan logis. Dengan hyperthreading, satu inti fisik berfungsi sebagai dua inti logis. Saya memiliki teknologi yang bersikeras bahwa prosesor yang memiliki thread adalah hal yang nyata, jadi saya menggambar di papan tulis prosesor dengan spindle thread yang mencuat dari itu.
@ TechnikEmpire Lihatlah intel.com/content/www/us/en/processors/core/… ini , mungkin Anda bisa menghubungi intel dan menggambar mereka juga.
g7k
24

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.

Jim Garrison
sumber
21

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

pkazen
sumber
4
Mengapa itu diturunkan? Maaf, tapi ini jawaban terbaik untuk pertanyaan ini. gonzalo membahas bagian yang berani dari pertanyaan, dan pkazen membahas judul. Kedua jawaban itu sangat berguna, tetapi jawaban pkazen relevan karena kami memiliki metode sistematis untuk memperkirakan jumlah utas. Dia bahkan memberikan rumus untuk algoritma linea.
tobiak777
1
Saya tidak mengundurkan diri tetapi jika saya melakukannya akan berdasarkan bahwa tidak ada penjelasan nyata mengapa atau bagaimana jumlah optimal utas terkait dengan kompleksitas algoritma, simpan dengan membaca seluruh artikel terkait, yang sudah lama dibaca (karena kerumitan artikel). Di luar itu, beberapa aspek artikel tidak jelas bagi saya, yang paling penting bagaimana hasil eksperimen mengkonfirmasi teori.
Codebling
Juga, saya percaya perhitungan ini mengasumsikan bahwa Anda memiliki jumlah core CPU yang tak terbatas. Meskipun ini informasi yang sangat berharga, pertanyaannya merujuk pada mesin nyata dengan sejumlah kecil inti.
Navneeth
9

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.

someneat
sumber
7

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.

Earlz
sumber
7

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.

mmr
sumber
3

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'.

man ps

Jika Anda ingin menghitung jumlah semua proses pengguna, Anda dapat menggunakan salah satu dari perintah ini:

  1. ps -aux| wc -l
  2. ps -eLf | wc -l

Menghitung jumlah proses pengguna:

  1. ps --User root | wc -l

Anda juga dapat menggunakan "htop" [Referensi] :

Menginstal di Ubuntu atau Debian:

sudo apt-get install htop

Menginstal di Redhat atau CentOS:

yum install htop
dnf install htop      [On Fedora 22+ releases]

Jika Anda ingin mengkompilasi htop dari kode sumber, Anda akan menemukannya di sini .

Saeed Zahedian Abroodi
sumber
2

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.

patroli
sumber
Itu tergantung pada apakah Anda ingin proses latar belakang pengguna berjalan seperti sampah saat aplikasi Anda berjalan. Untuk itu, Anda bisa menetapkan prioritas waktu-nyata untuk setiap utas dan mendapatkan jumlah daya maksimum. Tapi pengguna suka multitasking.
Earlz
2
Yah, kita sedang berhadapan dengan aplikasi ajaib yang dapat diparalel secara ideal Jika saya pernah membuat hal seperti itu, saya akan merasa berhak untuk memonopoli CPU sebanyak yang saya inginkan.
patros
2

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.

Olof Forshell
sumber
Saya tidak tahu Linux mana yang Anda bicarakan, tetapi blok saya sampai koneksi tiba. Saya sarankan Anda membaca beberapa hal tentang select () dan FD_SET () dan fungsi / makro yang serupa.
Alexis Wilke
Oke, jadi tidak ada formulir asinkron yang segera kembali?
Olof Forshell
Dari halaman manual select ():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.
Alexis Wilke
0

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.

Anycorn
sumber
0

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 ...

M. Gopal
sumber