Apakah mungkin untuk menulis kode (atau perangkat lunak lengkap, daripada sepotong kode) yang tidak akan berfungsi dengan baik ketika dijalankan pada CPU yang memiliki jumlah core kurang dari N? Tanpa mengeceknya secara eksplisit dan gagal dengan sengaja:
JIKA (noOfCores <4) MAKA tidak berjalan dengan baik dengan sengaja
Saya melihat persyaratan sistem minimum game ( Dragon Age: Inkuisisi ), dan menyatakan minimum CPU empat inti. Banyak pemain mengatakan itu TIDAK berjalan pada CPU dua-inti dan BAHKAN pada Intel Core i3s dengan dua fisik dan dua inti logis. Dan itu BUKAN masalah daya komputasi.
Dari pemahaman saya, utas sepenuhnya terisolasi dari CPU oleh OS karena itu tidak dapat dilakukan.
Hanya untuk membersihkan:
Saya TIDAK bertanya "Bisakah saya mencari tahu jumlah inti CPU dari kode, dan gagal dengan sengaja?" ... Kode semacam itu akan menjadi niat buruk (memaksa Anda untuk membeli CPU yang lebih mahal untuk menjalankan program - tanpa perlu daya komputasi). Saya meminta kode Anda, katakanlah, memiliki empat utas dan gagal ketika dua utas dijalankan pada inti fisik yang sama (tanpa secara eksplisit memeriksa informasi sistem dan sengaja gagal) .
Singkatnya, dapatkah ada perangkat lunak yang membutuhkan banyak inti, tanpa memerlukan daya komputasi tambahan yang berasal dari banyak inti? Itu hanya akan membutuhkan N inti fisik yang terpisah.
sumber
Jawaban:
Dimungkinkan untuk melakukan ini "secara tidak sengaja" dengan penggunaan afinitas inti secara ceroboh. Pertimbangkan kodesemu berikut:
Jika Anda memulai empat dari mereka pada CPU dua-inti, maka ada yang tidak beres dengan pengaturan afinitas inti atau Anda berakhir dengan dua utas memonopoli inti yang tersedia dan dua utas yang tidak pernah dijadwalkan. Pada titik tidak ada secara eksplisit bertanya berapa banyak core yang ada secara total.
(Jika Anda memiliki utas yang sudah berjalan lama, pengaturan afinitas CPU umumnya meningkatkan throughput)
Gagasan bahwa perusahaan game "memaksa" orang untuk membeli perangkat keras yang lebih mahal tanpa alasan yang baik tidak terlalu masuk akal. Itu hanya bisa kehilangan mereka pelanggan.
Sunting: posting ini sekarang telah mendapat 33 upvotes, yang cukup banyak mengingat bahwa itu didasarkan pada tebakan yang dididik!
Tampaknya orang-orang telah mendapatkan DA: Saya menjalankan, buruk, pada sistem dual-core: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Analisis itu menyebutkan bahwa situasinya akan sangat membaik jika hyperthreading dihidupkan. Mengingat bahwa HT tidak menambahkan unit instruksi masalah atau cache lagi, itu hanya memungkinkan satu utas berjalan sementara yang lain ada dalam ruang cache, yang menunjukkan dengan kuat bahwa itu terkait dengan murni jumlah utas.
Poster lain mengklaim bahwa mengubah driver grafis berfungsi: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; mengingat bahwa driver grafis cenderung menjadi sarang sampah dan penjahat, ini tidak mengejutkan. Satu set driver yang terkenal memiliki mode "benar & lambat" versus "cepat & salah" yang dipilih jika dipanggil dari QUAKE.EXE. Sangat mungkin bahwa driver berperilaku berbeda untuk jumlah CPU yang berbeda. Mungkin (kembali ke spekulasi) mekanisme sinkronisasi yang berbeda digunakan. Penyalahgunaan spinlocks ?
"Penyalahgunaan penguncian dan sinkronisasi primitif" adalah sumber bug yang sangat, sangat umum. (Bug yang seharusnya saya lihat di tempat kerja saat menulis ini adalah "macet jika mengubah pengaturan printer bersamaan dengan pekerjaan cetak selesai").
Sunting 2: komentar menyebutkan OS berusaha menghindari kelaparan utas. Perhatikan bahwa gim ini mungkin memiliki penjadwal kuasi internal sendiri untuk menetapkan pekerjaan ke utas, dan akan ada mekanisme serupa dalam kartu grafis itu sendiri (yang secara efektif merupakan sistem multitasking sendiri). Peluang bug di salah satu dari mereka atau interaksi di antara mereka cukup tinggi.
www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) adalah tesis pascasarjana tentang penjadwalan yang lebih baik untuk kartu grafis yang secara eksplisit menyebutkan bahwa mereka biasanya menggunakan penjadwalan pertama datang pertama dilayani, yang mudah diimplementasikan dalam sistem non-preemptive. Apakah situasinya membaik? Mungkin tidak.
sumber
Mungkin perlu memiliki 4 core karena aplikasi menjalankan empat tugas dalam utas paralel dan mengharapkannya untuk menyelesaikan hampir secara bersamaan.
Ketika setiap utas dieksekusi oleh inti yang terpisah dan semua utas memiliki beban kerja komputasi yang sama persis, mereka kemungkinan besar (tetapi jauh dari jaminan) untuk menyelesaikan kira-kira waktu yang sama. Tetapi ketika dua utas berjalan pada satu inti, waktunya akan jauh lebih mudah diprediksi karena inti akan mengubah konteks antara dua utas sepanjang waktu.
Bug yang terjadi karena timing thread yang tidak terduga disebut sebagai " kondisi balapan ".
Dalam konteks pengembangan game, satu arsitektur yang masuk akal dengan masalah seperti ini bisa menjadi salah satu di mana fitur yang berbeda dari game disimulasikan secara real-time oleh utas CPU yang berbeda. Ketika setiap fitur berjalan pada inti sendiri, mereka semua disimulasikan dengan kecepatan yang kira-kira sama. Tetapi ketika dua fitur berjalan pada satu inti, keduanya hanya akan disimulasikan setengah secepat dunia permainan, yang dapat menyebabkan semua jenis perilaku aneh.
Perhatikan bahwa arsitektur perangkat lunak yang bergantung pada utas independen yang berjalan dengan timing spesifik sangat rapuh dan merupakan tanda pemahaman yang sangat buruk tentang pemrograman bersamaan. Ada fitur yang tersedia di hampir semua API multithreading untuk menyinkronkan utas secara eksplisit untuk mencegah masalah seperti ini.
sumber
Tidak mungkin "persyaratan minimum" ini mewakili sesuatu di bawah ini yang tidak akan dijalankan oleh game. Jauh lebih mungkin adalah bahwa mereka mewakili sesuatu di bawah ini yang tidak akan dijalankan oleh permainan dengan kinerja yang dapat diterima. Tidak ada perusahaan game yang ingin berurusan dengan banyak pelanggan yang mengeluh tentang kinerja jelek ketika mereka menjalankannya pada kotak single core 1 Ghz, bahkan jika perangkat lunaknya dapat berjalan secara teknis. Jadi mereka mungkin sengaja merancang untuk gagal keras pada kotak dengan core lebih sedikit daripada yang akan memberi mereka kinerja yang dapat diterima.
Salah satu metrik penting dalam kinerja game adalah frame rate. Biasanya mereka berjalan pada 30 atau 60 frame per detik. Ini berarti bahwa mesin permainan harus membuat tampilan saat ini dari keadaan permainan dalam jumlah waktu yang tetap. Untuk mencapai 60 fps, hanya perlu sedikit lebih dari 16 msec untuk melakukan ini. Game dengan grafis kelas atas sangat terikat dengan CPU, jadi ada memberi dan menerima yang besar antara mencoba untuk mendorong kualitas yang lebih tinggi (yang membutuhkan lebih banyak waktu) dan kebutuhan untuk tetap berada dalam anggaran waktu ini. Dengan demikian, anggaran waktu untuk setiap frame sangat ketat.
Karena anggaran waktu terbatas, pengembang idealnya menginginkan akses eksklusif ke satu atau lebih inti. Mereka juga mungkin ingin dapat melakukan rendering barang-barang mereka dalam sebuah inti, secara eksklusif, karena apa yang harus dilakukan pada anggaran waktu itu, sementara hal-hal lain, seperti menghitung negara dunia, terjadi pada proses terpisah di mana itu tidak akan mengganggu.
Anda bisa, secara teori, menjejalkan semua ini ke satu inti, tetapi kemudian semuanya menjadi lebih sulit. Tiba-tiba Anda harus memastikan semua hal keadaan permainan terjadi cukup cepat, dan memungkinkan rendering Anda terjadi. Anda tidak bisa hanya membuat mereka dua utas perangkat lunak karena tidak ada cara untuk membuat OS memahami "utas A harus menyelesaikan jumlah pekerjaan X dalam 16 msecs terlepas dari apa yang dilakukan thread B".
Pengembang game tidak tertarik untuk membuat Anda membeli perangkat keras baru. Alasan mereka memiliki persyaratan sistem adalah karena biaya untuk mendukung mesin kelas bawah tidak sepadan.
sumber
Tiga utas realtime yang tidak pernah tidur dan satu utas lainnya. Jika ada kurang dari empat core, utas keempat tidak pernah berjalan. Jika utas keempat perlu berkomunikasi dengan salah satu utas realtime agar utas realtime selesai, kode tidak akan selesai dengan kurang dari empat inti.
Jelas jika utas realtime sedang menunggu sesuatu yang tidak memungkinkan mereka untuk tidur (seperti spinlock) perancang program mengacau.
sumber
Pertama-tama utas perangkat lunak tidak ada hubungannya dengan utas perangkat keras dan sering kali dicampuradukkan. Utas perangkat lunak adalah potongan kode yang dapat dikirim dan dijalankan sendiri dalam konteks proses. Utas perangkat keras sebagian besar dikelola oleh OS dan dikirim ke inti prosesor ketika berbicara tentang program reguler. Utas perangkat keras ini dikirim berdasarkan beban; dispatcher ulir perangkat keras bertindak kurang lebih seperti penyeimbang beban.
Namun ketika datang ke game, terutama game high-end, kadang-kadang utas perangkat keras dikelola oleh permainan itu sendiri atau permainan memerintahkan dispatcher utas perangkat keras apa yang harus dilakukan. Itu karena setiap tugas atau kelompok tugas tidak memiliki prioritas yang sama seperti dalam program normal. Karena zaman naga berasal dari studio game high-end menggunakan mesin-mesin high-end, saya dapat membayangkan bahwa itu menggunakan pengiriman "manual" dan kemudian jumlah core menjadi persyaratan sistem minimal. Program apa pun akan macet ketika saya mengirim sepotong kode ke inti fisik ke-3 yang berjalan pada mesin dengan hanya 1 atau 2 core.
sumber
Karena dimungkinkan untuk menggunakan virtualisasi untuk memiliki lebih banyak core virtual daripada fisik dan perangkat lunak tidak akan tahu itu berjalan pada virtualisasi dan sebaliknya berpikir bahwa itu memang memiliki banyak core fisik, saya akan mengatakan perangkat lunak seperti itu tidak mungkin.
Artinya, tidak mungkin untuk menulis perangkat lunak yang akan selalu berhenti di kurang dari N core.
Seperti yang telah ditunjukkan orang lain, ada solusi perangkat lunak yang berpotensi memeriksa, terutama jika OS dan kode yang digunakan memiliki sedikit perlindungan terhadap kondisi balapan ketika proses N dijalankan pada <N prosesor. Trik sebenarnya adalah kode yang akan gagal saat Anda memiliki prosesor kurang dari N tetapi tidak akan gagal ketika Anda memiliki prosesor N tetapi memiliki OS yang dapat menetapkan pekerjaan untuk prosesor yang kurang dari N.
sumber
Bisa jadi ada tiga utas yang melakukan sesuatu (menghasilkan latar belakang atau menghasilkan gerakan NPC) dan meneruskan acara ke urutan keempat, yang seharusnya mengagregasi / memfilter acara dan memperbarui model tampilan. Jika utas keempat tidak mendapatkan semua acara (karena tidak dijadwalkan pada inti) maka model tampilan tidak dapat diperbarui dengan benar. Ini mungkin hanya terjadi secara sporadis, tetapi inti tersebut harus tersedia kapan saja. Ini mungkin menjelaskan mengapa Anda tidak melihat penggunaan CPU yang tinggi sepanjang waktu, tetapi permainan tetap gagal berfungsi dengan baik.
sumber
Saya pikir Joshua sedang menuju jalan yang benar, hanya saja tidak sampai pada kesimpulan itu.
Misalkan Anda memiliki arsitektur di mana ada tiga utas yang ditulis untuk melakukan sebanyak yang mereka bisa - ketika mereka menyelesaikan apa yang mereka lakukan, mereka melakukannya lagi. Untuk menjaga kinerja agar utas ini tidak melepaskan kontrol untuk apa pun - mereka tidak ingin mengambil risiko kelambatan dari penjadwal tugas Windows. Selama ada 4 atau lebih core ini berfungsi dengan baik, gagal jika tidak ada.
Secara umum ini akan menjadi pemrograman yang buruk tetapi permainan adalah masalah lain - ketika Anda dihadapkan dengan pilihan antara desain yang lebih rendah pada semua perangkat keras atau desain yang lebih unggul pada perangkat keras yang cukup baik atau kegagalan pada perangkat keras yang lebih rendah biasanya pengembang permainan memilih membutuhkan perangkat keras.
sumber
Is it possible to write code (or complete software, rather than a piece of code) that won't work properly when run on a CPU that has less than N number of cores?
Benar. Penggunaan utas real-time akan menjadi contoh yang baik dari situasi di mana ini, tidak hanya mungkin, tetapi cara yang diinginkan (dan seringkali, satu-satunya cara yang benar) untuk menyelesaikan pekerjaan. Namun, utas waktu-nyata biasanya terbatas pada kernel OS, biasanya untuk driver yang perlu dapat menjamin bahwa peristiwa perangkat keras semacam itu ditangani dalam beberapa periode waktu tertentu. Anda seharusnya tidak memiliki utas real-time dalam aplikasi pengguna normal dan saya tidak yakin bahwa ada kemungkinan untuk memilikinya di aplikasi mode pengguna Windows. Secara umum, sistem operasi sengaja membuatnya mustahil untuk melakukan ini dari tanah pengguna justru karena itu memungkinkan aplikasi yang diberikan untuk mengambil alih kendali sistem.
Mengenai aplikasi pengguna lahan: Asumsi Anda bahwa memeriksa jumlah utas tertentu untuk menjalankannya tentu jahat maksudnya tidak benar. Misalnya, Anda dapat memiliki 2 tugas yang telah lama berjalan, kinerja-intensif yang membutuhkan inti untuk diri mereka sendiri. Terlepas dari kecepatan inti CPU, berbagi inti dengan utas lain dapat menjadi penurunan kinerja yang serius dan tidak dapat diterima karena meronta-ronta cache bersama dengan hukuman normal yang ditimbulkan oleh penggantian ulir (yang cukup besar.) Dalam hal ini, akan sangat masuk akal, khususnya untuk sebuah game, untuk mengatur setiap utas ini untuk memiliki afinitas hanya pada satu inti tertentu untuk masing-masing dan kemudian mengatur semua utas Anda yang lain untuk tidak memiliki afinitas pada 2 inti tersebut. Untuk melakukan ini, Anda
sumber
Kode apa pun yang menggunakan spinlocks dengan jumlah kunci pertentangan yang terlihat akan berkinerja sangat buruk (sampai batas di mana - untuk aplikasi seperti game - Anda dapat mengatakan "tidak berfungsi" ) jika jumlah utas melebihi jumlah inti.
Bayangkan, misalnya, sebuah utas produsen yang mengirimkan tugas ke antrian yang melayani 4 utas konsumen. Hanya ada dua inti:
Produser mencoba memperoleh spinlock, tetapi dipegang oleh konsumen yang menjalankan core lainnya. Dua core berjalan berbaris sementara produser berputar, menunggu kunci untuk dirilis. Ini sudah buruk, tetapi tidak seburuk yang akan didapat.
Sayangnya, utas konsumen berada di akhir kuantum waktunya, jadi sudah diutamakan, dan utas konsumen lain dijadwalkan. Mencoba untuk mendapatkan kunci, tetapi tentu saja kunci diambil, jadi sekarang dua core berputar dan menunggu sesuatu yang tidak mungkin terjadi.
Utas produsen mencapai akhir irisan waktu dan didahului, konsumen lain bangun. Sekali lagi, dua konsumen sedang menunggu kunci untuk dirilis, dan itu tidak akan terjadi sebelum dua kuantum waktu berlalu.
[...] Akhirnya konsumen yang memegang spinlock telah melepaskan kunci. Ini segera diambil oleh siapa pun yang berputar pada inti lainnya. Ada kemungkinan 75% (3 banding 1) bahwa itu adalah utas konsumen lainnya. Dengan kata lain, kemungkinan 75% produsernya masih mandek. Tentu saja ini berarti konsumen juga berhenti. Tanpa produser menghentikan tugas, mereka tidak akan melakukan apa pun.
Perhatikan bahwa ini bekerja pada prinsipnya dengan segala jenis penguncian, tidak hanya spinlocks - tetapi efek yang menghancurkan jauh lebih menonjol dengan spinlocks karena CPU terus membakar siklus sementara itu tidak mencapai apa-apa.
Sekarang bayangkan bahwa selain di atas beberapa programmer memiliki ide cemerlang untuk menggunakan utas khusus dengan afinitas ditetapkan ke inti pertama, sehingga RDTSC akan memberikan hasil yang dapat diandalkan pada semua prosesor (itu tidak akan tetap, tetapi beberapa orang berpikir begitu).
sumber
Jika saya mengerti apa yang Anda minta, itu mungkin, tetapi itu adalah hal yang sangat, sangat buruk.
Contoh kanonik dari apa yang Anda gambarkan adalah mempertahankan penghitung yang ditambahkan oleh banyak utas. Ini hampir tidak memerlukan apa pun dalam daya komputasi, tetapi membutuhkan koordinasi yang cermat di antara semua utas. Selama hanya satu utas pada satu waktu melakukan peningkatan (yang sebenarnya merupakan pembacaan diikuti oleh penambahan diikuti oleh penulisan), nilainya akan selalu benar. Ini karena satu utas akan selalu membaca nilai "sebelumnya" yang benar, tambahkan satu dan tulis nilai "selanjutnya" yang benar. Dapatkan dua utas ke tindakan pada saat yang sama dan keduanya akan membaca nilai "sebelumnya" yang sama, mendapatkan hasil yang sama dari kenaikan dan menulis nilai "berikutnya" yang sama. Penghitung secara efektif akan bertambah hanya sekali meskipun dua utas berpikir mereka masing-masing melakukannya.
Ketergantungan antara waktu dan kebenaran inilah yang oleh ilmu komputer disebut kondisi balapan .
Kondisi balapan seringkali dihindari dengan menggunakan mekanisme sinkronisasi untuk memastikan utas yang ingin beroperasi pada sepotong data yang dibagikan harus mengantre untuk akses. Penghitung yang dijelaskan di atas mungkin menggunakan kunci baca-tulis untuk ini.
Tanpa akses ke desain internal Dragon Age: Inkuisisi , yang dapat dilakukan siapa pun hanyalah berspekulasi tentang mengapa berperilaku seperti itu. Tapi saya akan mencoba berdasarkan beberapa hal yang saya lihat dilakukan dalam pengalaman saya sendiri:
Mungkin saja program ini didasarkan pada empat utas yang telah disetel sehingga semuanya berfungsi ketika utas sebagian besar berjalan tanpa gangguan pada inti fisik mereka sendiri. "Penyetelan" dapat dilakukan dalam bentuk penyusunan ulang kode atau memasukkan tidur di tempat-tempat strategis untuk mengurangi bug yang disebabkan oleh kondisi ras yang muncul selama pengembangan. Sekali lagi, ini semua dugaan, tetapi saya telah melihat kondisi balapan "diselesaikan" dengan cara itu lebih dari yang saya perhitungkan.
Menjalankan program seperti itu pada sesuatu yang kurang mampu daripada lingkungan yang disetelnya memperkenalkan perubahan waktu yang merupakan hasil dari kode yang tidak berjalan secepat atau, lebih mungkin, konteks switch. Sakelar konteks terjadi dalam cara fisik (yaitu, inti fisik CPU beralih di antara pekerjaan yang dipegang inti logisnya) dan logis (yaitu, OS pada CPU memberikan pekerjaan pada inti) cara, tetapi keduanya merupakan perbedaan yang signifikan dari apa yang akan menjadi waktu eksekusi "yang diharapkan". Itu bisa memunculkan perilaku buruk.
Jika Dragon Age: Inkuisisi tidak mengambil langkah sederhana untuk memastikan ada cukup inti fisik yang tersedia sebelum melanjutkan, itu salah EA. Mereka mungkin menghabiskan banyak uang dukungan panggilan dan email dari orang-orang yang mencoba menjalankan permainan pada perangkat keras yang terlalu sedikit.
sumber
Windows memiliki fungsionalitas bawaan untuk ini: fungsi GetLogicalProcessorInformation ada di Windows API . Anda dapat memanggilnya dari program Anda untuk mendapatkan informasi tentang core, core virtual, dan hyperthreading.
Jadi jawaban untuk pertanyaan Anda adalah: Ya.
sumber
/proc/cpuinfo
dansysconf(_SC_NPROCESSORS_ONLN)
(yang terakhir disebutkan dalam POSIX). Menggunakan info untuk menegakkan ambang batas kinerja minimum masih merupakan bentuk yang sangat buruk.