Mengapa serat tidak bisa menggunakan banyak prosesor?

8

Tampaknya perbedaan antara serat dan benang adalah bahwa serat dijadwalkan secara kooperatif, sedangkan benang dijadwalkan sebelumnya. Inti dari penjadwal tampak seperti cara untuk membuat sumber daya prosesor serial bertindak secara paralel, dengan "membagi waktu" CPU. Namun, pada prosesor dual-core dengan masing-masing core menjalankan utasnya sendiri, saya berasumsi tidak perlu menghentikan eksekusi satu utas untuk yang lainnya untuk melanjutkan karena mereka tidak "berbagi waktu" satu prosesor.

Jadi, jika perbedaan antara ulir dan serat adalah cara mereka terputus oleh penjadwal, dan interupsi tidak diperlukan ketika berjalan pada inti yang terpisah secara fisik, mengapa serat tidak dapat mengambil keuntungan dari beberapa inti prosesor saat benang dapat?

Sumber kebingungan:

wikipedia ..mlyly

  1. http://en.wikipedia.org/wiki/Fiber_%28computer_science%29

    Kerugiannya adalah serat tidak bisa menggunakan mesin multiprosesor tanpa juga menggunakan benang preemptive

  2. http://en.wikipedia.org/wiki/Computer_multitasking#Multithreading

    ... [serat] cenderung kehilangan sebagian atau semua manfaat utas pada mesin dengan banyak prosesor.

James M. Lay
sumber

Jawaban:

9

Perbedaan utama, seperti yang Anda tunjukkan dalam pertanyaan Anda, adalah apakah penjadwal akan mendahului utas. Cara seorang programmer berpikir tentang berbagi struktur data atau tentang sinkronisasi antara "utas" sangat berbeda dalam sistem preemptive dan kooperatif.

Dalam sistem kooperatif (yang dikenal dengan banyak nama, kooperatif multi-tasking , multi-tasking nonpreemptive , level pengguna , benang hijau , dan serat adalah lima yang umum saat ini) programmer dijamin bahwa kode mereka akan berjalan secara atom selama mereka tidak melakukan panggilan sistem atau panggilan apa pun yield(). Ini membuatnya sangat mudah untuk berurusan dengan struktur data yang dibagi di antara banyak serat. Kecuali jika Anda perlu membuat panggilan sistem sebagai bagian dari bagian kritis, bagian penting tidak perlu ditandai (dengan mutex lockdan unlockpanggilan, misalnya). Jadi dalam kode seperti:

x = x + y
y = 2 * x

programmer tidak perlu khawatir bahwa serat lain dapat bekerja dengan xdan yvariabel - variabel pada saat yang sama. xdan yakan diperbarui bersama secara atomik dari perspektif semua serat lainnya. Demikian pula, semua serat dapat berbagi beberapa struktur yang lebih rumit, seperti pohon dan panggilan seperti tree.insert(key, value)tidak perlu dilindungi oleh mutex atau bagian kritis.

Sebaliknya, dalam sistem multithreading preemptive, seperti dengan thread paralel / multicore yang benar-benar, setiap kemungkinan interleaving instruksi antara thread dimungkinkan kecuali ada bagian kritis yang eksplisit. Interupsi dan preemption bisa terjadi antara dua instruksi. Dalam contoh di atas:

 thread 0                thread 1
                         < thread 1 could read or modify x or y at this point
 read x
                         < thread 1 could read or modify x or y at this point
 read y
                         < thread 1 could read or modify x or y at this point
 add x and y
                         < thread 1 could read or modify x or y at this point
 write the result back into x
                         < thread 1 could read or modify x or y at this point
 read x
                         < thread 1 could read or modify x or y at this point
 multiply by 2
                         < thread 1 could read or modify x or y at this point
 write the result back into y
                         < thread 1 could read or modify x or y at this point

Jadi, agar benar pada sistem preemptive, atau pada sistem dengan utas yang benar-benar paralel, Anda harus mengelilingi setiap bagian penting dengan semacam sinkronisasi, seperti mutex lockdi awal dan mutex unlockdi akhir.

Serat dengan demikian lebih mirip dengan pustaka i / o asinkron daripada dibandingkan dengan thread preemptive atau thread yang benar-benar paralel. Penjadwal serat dipanggil dan dapat mengganti serat selama operasi latensi panjang i / o. Ini dapat memberikan manfaat beberapa operasi i / o simultan tanpa memerlukan operasi sinkronisasi di sekitar bagian-bagian penting. Jadi, menggunakan serat dapat, mungkin, memiliki kompleksitas pemrograman yang lebih sedikit daripada benang preemptive atau benar-benar paralel, tetapi kurangnya sinkronisasi di sekitar bagian-bagian penting akan menyebabkan hasil yang merusak jika Anda mencoba menjalankan serat dengan benar secara simultan atau preemptive.

Logika Pengembaraan
sumber
Saya pikir beberapa menyebutkan mungkin harus dibuat dari 1. sistem hybrid di mana sistem thread tingkat pengguna mengambil alih mendistribusikan (banyak) thread tingkat pengguna di (beberapa) core CPU dan 2. fakta bahwa ketika pemrograman pada "bare metal" , dimungkinkan untuk mendapatkan multi-pemrosesan tanpa preemption.
dfeuer
1
@ PDFeuer Saya tidak berpikir pertanyaannya adalah menanyakan semua cara yang mungkin berbeda untuk memanfaatkan multiprosesor. Pertanyaan yang saya baca adalah "mengapa serat tidak bisa (juga dikenal sebagai tugas non-preemptive) diperlakukan seperti benang preemptive?" Jika Anda mengasumsikan paralelisme nyata maka Anda harus melakukan sinkronisasi dengan benar, sehingga Anda tidak lagi memiliki "serat".
Pengembaraan Logika
1
Jawaban yang indah Serat tidak dapat menjamin keamanan karena program akan menganggapnya memiliki akses eksklusif ke sumber daya bersama sampai ditentukan titik interupsi, di mana utas menganggap akses / mutasi dapat dilakukan pada titik mana pun; jelas asumsi yang lebih aman ketika banyak node yang benar-benar paralel berinteraksi dengan data yang sama.
James M. Lay
6

Jawabannya sebenarnya adalah mereka bisa, tetapi ada keinginan untuk tidak melakukannya.

Serat digunakan karena memungkinkan Anda mengontrol bagaimana penjadwalan terjadi. Dengan demikian, jauh lebih mudah untuk merancang beberapa algoritma menggunakan serat karena programmer telah mengatakan di mana serat dieksekusi pada suatu waktu. Namun, jika Anda ingin dua serat dieksekusi pada dua inti yang berbeda secara bersamaan, Anda harus menjadwalkannya secara manual.

Utas memberi kendali kode mana yang dieksekusi ke OS. Sebagai gantinya, OS menangani banyak tugas buruk untuk Anda. Beberapa algoritma menjadi lebih sulit, karena programmer memiliki lebih sedikit suara mengenai kode mana yang dieksekusi pada waktu tertentu, sehingga lebih banyak kasus yang tidak terduga dapat muncul. Alat-alat seperti mutex dan semaphore ditambahkan ke OS untuk memberikan programmer kontrol yang cukup untuk membuat utas bermanfaat dan mengalahkan beberapa ketidakpastian, tanpa menghalangi programmer.

Ini mengarah ke sesuatu yang bahkan lebih penting daripada kooperatif vs preemptive: serat dikontrol oleh programmer, sedangkan utas dikontrol oleh OS.

Anda tidak ingin harus menelurkan serat pada prosesor lain. Perintah tingkat perakitan untuk melakukannya sangat rumit, dan sering kali khusus untuk prosesor. Anda tidak ingin harus menulis 15 versi kode yang berbeda untuk menangani prosesor ini, jadi Anda beralih ke OS. Tugas OS adalah untuk memisahkan perbedaan-perbedaan ini. Hasilnya adalah "utas."

Serat berjalan di atas utas. Mereka tidak lari sendiri. Dengan demikian, jika Anda ingin menjalankan dua serat pada inti yang berbeda, Anda dapat memunculkan dua benang, dan menjalankan serat pada masing-masingnya. Dalam banyak penerapan serat, Anda dapat melakukan ini dengan mudah. Dukungan multi-core tidak berasal dari serat, tetapi dari benang.

Menjadi mudah untuk menunjukkan bahwa, kecuali jika Anda ingin menulis kode spesifik prosesor Anda sendiri, tidak ada yang dapat Anda lakukan dengan menetapkan serat ke beberapa inti yang tidak dapat Anda lakukan dengan membuat utas dan menetapkan serat ke masing-masing. Salah satu aturan favorit saya untuk desain API adalah "API tidak dilakukan ketika Anda telah selesai menambahkan semuanya, melainkan ketika Anda tidak lagi dapat menemukan hal lain untuk dihapus." Mengingat multi-core ditangani dengan sempurna oleh hosting serat pada utas, tidak ada alasan untuk menyulitkan API serat dengan menambahkan multi-inti pada tingkat itu.

Cort Ammon
sumber