Program yang mengklaimnya tidak ramah multi-core

17

Anda melihat frasa ini atau sejenisnya berputar-putar dari waktu ke waktu, umumnya merujuk pada sebuah program yang mengklaim mereka tidak dirancang untuk mengambil keuntungan penuh dari prosesor multi-core. Ini umum terutama dengan pemrograman video game. (tentu saja banyak program tidak memiliki konkurensi dan tidak memerlukannya, seperti skrip dasar, dll).

Bagaimana ini bisa terjadi? Banyak program (terutama game) yang secara inheren menggunakan konkurensi, dan karena OS bertanggung jawab atas penjadwalan tugas pada CPU, maka apakah program-program ini secara inheren tidak mengambil keuntungan dari beberapa core yang tersedia? Apa artinya dalam konteks ini untuk "mengambil keuntungan dari banyak core"? Apakah pengembang ini sebenarnya melarang penjadwalan tugas OS dan memaksa afinitas atau penjadwalan mereka sendiri? (Kedengarannya seperti masalah stabilitas utama).

Saya seorang programmer Java, jadi mungkin saya tidak harus berurusan dengan ini karena abstraksi atau yang lainnya.

SnakeDoc
sumber
11
Kemungkinan besar adalah bahwa jalan pintas diambil dalam sinkronisasi, yang bekerja untuk sistem prosesor / inti tunggal tetapi putus dengan konkurensi sebenarnya dari beberapa prosesor / inti.
Bart van Ingen Schenau
@ BartvanIngenSchenau: Ini benar. Anda harus mengembangkan ini dan mempostingnya sebagai jawaban. Saya pikir semua yang lain tidak mengerti.
kevin cline
1
Saya pikir @Bart sangat dekat. Namun, s / work / tampaknya berfungsi / dan akan lebih dekat dengan tanda.
Ben Voigt
sebagai samping - saya sudah memiliki pengalaman ini sebagai pengguna daripada seorang programmer - Ground Control 2 di windows XP. Saya perlu mengatur afinitas inti menjadi hanya satu inti pada sistem multicore agar dapat berjalan dengan baik, jika tidak semua animasi (infact seluruh permainan) akan berjalan pada kecepatan 10x, yang sementara menjadi lebih dari tantangan memang sedikit menjengkelkan setelah beberapa saat . Saya tidak melakukan pekerjaan apa pun pada permainan, tetapi menurut saya, beberapa bagian dari permainan tampaknya mengandalkan prosesor hanya melakukan sejumlah pekerjaan pada saat yang sama.
jammypeach

Jawaban:

28

Konkurensi yang baik membutuhkan lebih dari sekadar melemparkan beberapa utas dalam suatu aplikasi dan berharap yang terbaik. Ada rentang bagaimana program bersamaan dapat berjalan dari paralel memalukan ke berurutan murni. Setiap program yang diberikan dapat menggunakan hukum Amdahl untuk mengungkapkan seberapa scalable suatu masalah atau algoritma. Beberapa kualifikasi untuk aplikasi paralel yang memalukan adalah:

  • Tidak ada status bersama, setiap fungsi hanya tergantung pada parameter yang diteruskan
  • Tidak ada akses ke perangkat fisik (kartu grafis, hard drive, dll)

Ada kualifikasi lain, tetapi hanya dengan dua ini kita dapat memahami mengapa gim tertentu tidak semudah yang Anda bayangkan untuk memanfaatkan banyak inti. Untuk satu, model dunia yang akan dirender harus dibagikan sebagai fungsi yang berbeda menghitung fisika, gerakan, menerapkan kecerdasan buatan dll. Kedua, setiap bingkai model permainan ini harus ditampilkan di layar dengan kartu grafis.

Agar adil, banyak pembuat game menggunakan mesin game yang diproduksi oleh pihak ketiga. Butuh beberapa saat, tetapi mesin-mesin permainan pihak ketiga ini sekarang jauh lebih sejajar dari sebelumnya.

Ada tantangan arsitektur yang lebih besar dalam berurusan dengan konkurensi efektif

Concurrency dapat mengambil banyak bentuk, dari menjalankan tugas di latar belakang hingga dukungan arsitektur penuh untuk concurrency. Beberapa bahasa memberi Anda fitur konkurensi yang sangat kuat seperti ERLANG , tetapi mengharuskan Anda untuk berpikir sangat berbeda tentang bagaimana Anda membangun aplikasi Anda.

Tidak setiap program benar-benar membutuhkan kompleksitas dukungan multicore penuh. Salah satu contohnya adalah perangkat lunak pajak, atau aplikasi yang didorong oleh formulir. Ketika sebagian besar waktu Anda dihabiskan menunggu pengguna untuk melakukan sesuatu, kompleksitas aplikasi multithreaded tidak begitu berguna.

Beberapa aplikasi memberikan solusi paralel yang lebih memalukan, seperti aplikasi web. Dalam hal ini, platform dimulai paralel memalukan dan terserah Anda tidak harus memaksakan pertengkaran thread.

Garis bawah:

Tidak semua aplikasi benar-benar terluka karena tidak memanfaatkan banyak utas (dan karenanya, inti). Untuk orang-orang yang terluka oleh itu, kadang-kadang perhitungan tidak ramah dengan pemrosesan paralel atau overhead untuk mengoordinasikannya akan membuat aplikasi lebih rapuh. Sayangnya, pemrosesan paralel masih tidak semudah yang seharusnya dilakukan dengan baik.

Berin Loritsch
sumber
Ini adalah analisis yang bagus. Satu hal yang menggangguku adalah pendapat Anda tentang program dunia nyata yang seringkali tidak memalukan dan karenanya sulit untuk diparalelkan: Walaupun mungkin tidak mungkin untuk melakukan hal yang sama secara paralel, mungkin sangat mudah untuk melakukan hal-hal yang berbeda secara paralel ( misalnya dalam arsitektur pipa, atau dengan utas UI yang terpisah).
amon
8
Poin sebenarnya adalah bahwa Anda perlu mendesain untuk eksekusi paralel, dan jika tidak, Anda dibatasi oleh kurangnya desain. Saya setuju bahwa bisa sangat mudah untuk melakukan hal-hal yang berbeda secara paralel, tetapi tidak jika itu adalah aplikasi yang sudah ada dengan harapan pengguna yang tinggi. Dalam hal ini mungkin perlu menulis ulang untuk membuatnya mungkin. Penulisan ulang secara inheren berisiko, tetapi kadang-kadang Anda dapat membuat argumen yang bagus untuk mereka. Saya telah melakukan beberapa penulisan ulang yang memaksimalkan pemrosesan paralel sambil mempertahankan kode sebanyak mungkin. Ada banyak faktor tersembunyi.
Berin Loritsch
Jawaban yang bagus Mungkin perlu ditekankan bahwa tidak hanya akan ada pengembalian yang semakin rendah dalam memparalelkan beberapa sistem, tetapi beberapa bahkan mungkin menjadi lebih lambat karena overhead yang diperlukan untuk membuatnya paralel. Secara khusus, banyak semafor / kunci dan pengalihan konteks dapat memiliki efek buruk pada runtime. Pergantian konteks khususnya dapat mengurangi efektivitas cache, yang merupakan masalah non-sepele jika Anda berada di titik mengoptimalkan sistem Anda. Contoh OP tentang mesin permainan membuat saya ingat untuk mendengar lebih banyak tentang mengoptimalkan caching daripada akses paralel.
Gankro
35

Banyak program (terutama game) yang secara inheren menggunakan konkurensi,

Tidak, sebenarnya sebaliknya. Sebagian besar aplikasi ditulis dalam satu pola pikir utas, dan pengembang tidak pernah membuat perubahan yang diperlukan untuk mendukung konkurensi.

Di C, C ++, dan C # Anda harus memberi tahu aplikasi secara eksplisit untuk memulai utas dan / atau proses baru.

Saya pikir Anda terlalu fokus pada penjadwalan utas dan tidak cukup pada penanganan data dalam utas potensial. Berbagi data di utas dan / atau proses memerlukan beberapa bentuk sinkronisasi. Jika Anda mengubah aplikasi untuk menggunakan banyak utas tetapi gagal untuk menyinkronkannya maka Anda mungkin akan melihat banyak kesulitan untuk melacak bug dalam kode.

Untuk aplikasi multi-utas yang telah saya kerjakan, saya umumnya tidak pernah khawatir tentang pengiriman dan hanya tentang sinkronisasi data. Satu-satunya waktu saya harus khawatir tentang pengiriman adalah ketika saya mengejar kondisi balapan karena sinkronisasi data yang salah.

Secara umum, ketika suatu aplikasi mengatakan itu tidak dapat menggunakan beberapa core maka itu berarti mereka tidak memiliki sinkronisasi untuk melindungi manipulasi data.


sumber
Apakah ini benar bahkan untuk program modern baru dari pengembang / penerbit besar? Ketika saya duduk dan menulis sebuah program, salah satu hal pertama dalam tahap desain yang saya pikirkan adalah, apakah saya perlu konkurensi? Karena dapat menghasilkan desain yang sangat berbeda. Permainan pada khususnya harus memiliki tingkat konkurensi, jika tidak, permainan akan membeku ketika salah satu dari seribu model di layar mencoba melakukan sesuatu ...?
SnakeDoc
5
@SnakeDoc - Saya pikir Anda membingungkan domain Anda di sana. Perusahaan-perusahaan Big Game tentu saja menulis dengan concurrency, tetapi saya belum melihat game dari Big Game yang tidak mendukung concurrency. Aplikasi & game yang saya lihat tidak dapat mendukung concurrency umumnya dari toko-toko kecil / pengembang individu di mana mereka tidak akan memulai dengan pola pikir itu. Dan pada titik tertentu dalam evolusi aplikasi, menjadi tidak mungkin untuk melakukan konkurensi setelah fakta. Dan beberapa aplikasi tidak pernah dimaksudkan untuk melakukan cukup untuk membenarkan menjadi berbarengan.
Dan juga beberapa game berkembang di konten baru (grafik dan gameplay), tanpa harus memperbarui mesin game (implementasi kode). Dengan demikian, mesin game bisa ketinggalan bertahun-tahun dalam teknologi.
rwong
6
@SnakeDoc: Anda tidak perlu konkurensi untuk berurusan dengan ribuan model di layar. Ini tidak seperti setiap objek dalam gim Anda membutuhkan utasnya sendiri untuk mensimulasikannya; satu utas dapat menangani pembaruan untuk semua yang ada di layar pada setiap catatan waktu.
user2357112 mendukung Monica
13

Ini bukan tentang banyak inti tetapi tentang banyak utas. OS dapat menjadwalkan utas untuk dijalankan pada inti apa pun yang disukainya, dan penjadwalan ini transparan untuk program yang dijadwalkan. Namun, banyak program tidak ditulis menggunakan banyak utas, sehingga hanya bisa berjalan pada satu inti sekaligus.

Mengapa saya menulis program single-threaded? Mereka lebih mudah untuk ditulis dan lebih mudah untuk di-debug: satu hal terjadi secara berurutan (alih-alih banyak hal terjadi sekaligus dan mungkin saling bertentangan). Atau program Anda mungkin tidak menargetkan mesin multi-core (seperti halnya game-game lama). Dalam beberapa kasus, program multi-ulir bahkan dapat berjalan lebih lambat daripada versi satu-ulir jika overhead dari konteks-switch dan komunikasi antara thread melebihi kecepatan yang diperoleh dengan eksekusi paralel (beberapa bagian dari program mungkin tidak dapat diparalelkan).

amon
sumber
8

Ini bukan jawaban lengkap. Ini adalah kisah peringatan.

Suatu hari saya pikir saya akan menunjukkan kepada siswa dalam kursus pemrograman bersamaan saya quicksort paralel. Quicksort harus sejajar dengan baik, pikir saya. Saya menggunakan dua utas. Jalankan di komputer single core saya. Hasilnya adalah:

  • 14 detik untuk versi utas tunggal.
  • 15 detik untuk versi 2-utas.

Ini tentang apa yang saya harapkan.

Lalu saya mencobanya pada mesin dual-core yang lebih baru.

  • 11 detik untuk versi single-threaded.
  • 20 detik untuk versi 2-utas.

Kedua utas berbagi antrian tugas yang tersisa. Tampaknya bidang objek antrian sedang bolak-balik antara cache satu inti dan yang lain.

Theodore Norvell
sumber
2
Berapa banyak elemen array yang Anda uji? Mungkin mergesort akan lebih cocok karena pemrograman multi-inti akan memerlukan penyalinan data untuk menghindari konflik cache-line?
rwong
2
@ rwong Ada 10.000.000 elemen array. Tentu saja mergesort akan berparalel dengan baik. Seandainya saya menggunakan semacam penggabungan, saya mungkin tidak akan mendapat pelajaran yang bermanfaat.
Theodore Norvell
1
@ ArchlaudPierre Saya akan mempertimbangkan untuk memparalelkan algoritma apa pun. Quicksort menarik karena Anda dapat menggunakan pendekatan bag-of-task untuknya. Karena tugasnya independen, intuisi saya adalah bahwa itu harus menjadi contoh paralelisme yang memalukan. Saya harus menyebutkan bahwa, setelah sedikit penyetelan, itu benar-benar mendapat peningkatan mendekati 2.
Theodore Norvell
1
@ Jules Jawabannya adalah penyeimbangan beban. Saya juga ingin menulisnya dengan cara yang membuat jumlah utas mudah diubah. Pendekatan Anda menggeneralisasi dengan baik ke kekuatan 2, tetapi tidak begitu baik untuk jumlah utas lainnya.
Theodore Norvell
2
@MaciejPiechotka Moral adalah hampir semua hal yang Anda sarankan. Tetapi kembali ke OP, saya pikir moral yang paling relevan adalah bahwa program multithread mungkin benar-benar berjalan (jauh) lebih lambat pada arsitektur multi-inti daripada pada prosesor inti tunggal, kecuali upaya telah dilakukan untuk memastikan sebaliknya.
Theodore Norvell