Apa yang dimaksud dengan target Visual Studio "CPU Apa"?

496

Saya memiliki beberapa kebingungan terkait dengan opsi .NET platform build di Visual Studio 2008.

Apa target kompilasi "Any CPU", dan jenis file apa yang dihasilkannya? Saya memeriksa executable output dari build "Any CPU" ini dan menemukan bahwa mereka adalah executable x86 (yang tidak akan melihatnya!). Jadi, apakah ada perbedaan antara penargetan yang dapat dieksekusi ke x86 vs "Any CPU"?

Hal lain yang saya perhatikan, adalah bahwa proyek C ++ yang dikelola tidak memiliki platform ini sebagai opsi. Mengapa demikian? Apakah itu berarti bahwa kecurigaan saya tentang executable "Any CPU" menjadi yang 32-bit benar?

galet
sumber
4
Satu hal lagi yang perlu dipertimbangkan ketika menentukan target platform mana yang akan digunakan: jika target proyek Startup adalah Any CPUdan Anda menjalankan OS 64 bit, Anda kehilangan kemampuan untuk Mengedit dan melanjutkan saat debugging. (Anda secara efektif men-debug proses 64bit). Anda bisa membuat target proyek Startupx86 untuk mengelak dari ini saat debugging. (Majelis yang dirujuk dari proyek startup dapat terus menargetkan Any CPU.
Cristian Diaconescu
8
@CristiDiaconescu Dengan VS2013 Sunting dan lanjutkan sekarang dimungkinkan
ms007
Saya pikir harus ada beberapa catatan di sini tentang apakah proyek tersebut merupakan aplikasi atau perpustakaan kelas karena menetapkan bitness target untuk yang terakhir dapat mempengaruhi ketersediaannya untuk mengkonsumsi aplikasi tergantung pada platform. Saya mengalami ini dengan x86perpustakaan sedang dikonsumsi oleh AnyCPUaplikasi di mana saya harus mengatur Prefer 32-bituntuk menghindari kesalahan memuat.
SteveCinq

Jawaban:

386

Sebuah AnyCPU perakitan akan JIT kode 64-bit saat dimuat ke dalam proses 64-bit dan 32 bit saat dimuat ke dalam proses 32-bit.

Dengan membatasi CPU Anda akan mengatakan: Ada sesuatu yang digunakan oleh majelis (sesuatu yang kemungkinan tidak dikelola) yang membutuhkan 32 bit atau 64 bit.

AnthonyWJones
sumber
3
jadi, bagaimana cara menghasilkan rakitan yang akan JIT ke x64 di C ++?
galets
50
Proyek C ++ mengkompilasi ke kode asli, sehingga kompiler JIT tidak terlibat ... dengan demikian, Anda tidak dapat melakukan apa yang Anda minta.
cplotts
7
@plotts: sejak @galets menanyakan pertanyaan ini 3 bulan lalu, sepertinya dia tidak akan melihat jawaban Anda. Gunakan awalan @galets dalam komentar Anda mirip dengan yang saya miliki di sini sehingga dia mendapat peringatan tentang jawaban Anda.
AnthonyWJones
4
@AnthonyWJones Secara umum Anda benar, kecuali di mana pengguna adalah OP dari pertanyaan, seperti dalam kasus ini, karena mereka akan mendapat pemberitahuan tentang semua komentar.
Mark Hurd
12
@ MarkHurd Sebenarnya, dalam hal ini, OP tidak akan diberitahu. OP's tidak mendapatkan pemberitahuan komentar atas jawaban kecuali mereka secara khusus melakukan ping dengan sintaks @. OP hanya secara otomatis mendapat pemberitahuan tentang komentar yang ditambahkan ke pertanyaan awal mereka.
RSW
322

Saya pikir sebagian besar hal penting telah dikatakan, tetapi saya hanya berpikir saya akan menambahkan satu hal: Jika Anda mengkompilasi sebagai Any CPU dan berjalan pada platform x64, maka Anda tidak akan dapat memuat file DLL 32-bit, karena aplikasi Anda tidak dimulai di WoW64 , tetapi file DLL tersebut perlu dijalankan di sana.

Jika Anda mengkompilasi sebagai x86, maka sistem x64 akan menjalankan aplikasi Anda di WoW64, dan Anda akan dapat memuat file DLL 32-bit.

Jadi saya pikir Anda harus memilih "Any CPU" jika dependensi Anda dapat berjalan di lingkungan mana pun, tetapi pilih x86 jika Anda memiliki dependensi 32-bit. Artikel dari Microsoft ini menjelaskan sedikit:

/ CLRIMAGETYPE (Tentukan Jenis Gambar CLR)

Secara kebetulan, dokumentasi Microsoft lainnya ini setuju bahwa x86 biasanya merupakan pilihan yang lebih portabel:

Memilih x86 biasanya merupakan konfigurasi teraman untuk paket aplikasi karena akan berjalan di hampir setiap perangkat. Pada beberapa perangkat, paket aplikasi dengan konfigurasi x86 tidak akan berjalan, seperti Xbox atau beberapa perangkat IoT Core. Namun, untuk PC, paket x86 adalah pilihan paling aman dan memiliki jangkauan terbesar untuk penyebaran perangkat. Sebagian besar perangkat Windows 10 terus menjalankan versi Windows x86.

Paul A Jungwirth
sumber
2
Mungkin Anda dapat mengedit jawaban Anda untuk mengatakan bagaimana seseorang dapat menentukan apakah DLL yang diberikan hanya 32-bit. Sejauh yang saya tahu, ini harus mencari tahu. Saya pikir kami berharap untuk DLL yang juga "Any CPU", daripada hanya x86 saja.
Dan W
Memberi +1 perbedaan penting. Diperlukan untuk menggunakan dependensi 32 bit (yang tidak diidentifikasi seperti itu). Tidak dapat menemukan pesan kesalahan runtime kriptik. Pada firasat mengubah target cpu dan berhasil tetapi pergi mencari "mengapa". Akan lebih baik suatu hari nanti ketika semuanya 64 bit dan masalah ketidakcocokan akan tampak aneh seperti 16bit vs 32bit sekarang.
Gerald Davis
2
@GeraldDavis - Saya setuju. Ironinya adalah tidak ada alasan teknologi untuk tidak dapat mencampur dependensi 32-bit dan 64-bit (hanya kurangnya lapisan thunking di CLR) dan saya kecewa kembali pada hari-hari awal. NET ketika saya melihat bit- ness masih sesuatu yang perlu dipertimbangkan ketika menggunakan (mengingat ini adalah VM / JIT itu akan menjadi kesempatan untuk memberikan nilai tambah yang sedikit lebih).
codenheim
1
@mrjoltcola: Bahkan lebih buruk dari itu adalah cara Microsoft memutuskan karena alasan saya tidak dapat memahami bahwa entri registri harus dibagi menjadi 32-bit dan 64-bit semesta bahkan jika mereka mengontrol hal-hal seperti warna layar, pengaturan default, dll.
supercat
Ini adalah jawaban yang saya cari ... Terima kasih!
Murat dari Daminion Software
52

Berikut ini ikhtisar singkat yang menjelaskan berbagai target pembangunan.

Dari pengalaman saya sendiri, jika Anda ingin membangun sebuah proyek yang akan berjalan pada platform x86 dan x64, dan Anda tidak memiliki optimisasi x64 spesifik, saya akan mengubah build untuk secara spesifik mengatakan "x86."

Alasan untuk ini adalah kadang-kadang Anda bisa mendapatkan beberapa file DLL yang bertabrakan atau kode yang akhirnya menabrak WoW di lingkungan x64. Dengan menentukan secara spesifik x86, OS x64 akan memperlakukan aplikasi sebagai aplikasi x86 murni dan memastikan semuanya berjalan dengan lancar.

Dillie-O
sumber
37
Yang bisa mengerikan jika Anda menulis untuk lingkungan server dan ingin aplikasi Anda dapat menggunakan lebih dari 2GB memori. Anda juga memilih keluar dari optimasi JIT x64 yang suatu hari nanti mungkin akan gagal.
Austin Harris
Jumlah masalah runtime yang saya miliki dengan kompilasi AnyCPU adalah semua pembenaran yang saya butuhkan untuk berhenti menggunakannya sebagai opsi build kecuali seseorang telah secara eksplisit meminta binari yang bekerja pada keduanya. Saya belum punya orang yang meminta binari x86 lebih dari x64 untuk apa pun dalam lebih dari 10 tahun.
kayleeFrye_onDeck
2
"Dengan secara spesifik menentukan x86, OS x64 akan memperlakukan aplikasi sebagai aplikasi x86 murni dan memastikan semuanya berjalan dengan lancar." - Maaf, saya tidak setuju. x64 OS masih akan menjalankan aplikasi x86 Anda di dalam WOW64
Mandeep Janjua
Ini hanya saran buruk untuk seseorang yang tidak sepenuhnya memahami dampaknya. @AustinHarris memberikan contoh yang bagus. Bayangkan sebuah proses pekerja web terbatas hanya beberapa GB RAM (saya baru-baru ini harus berurusan dengan ini dalam produksi).
rgoliveira
47

Lihat artikel Visual Studio .NET Platform Target Dijelaskan .

Pengaturan default, "Any CPU", berarti bahwa rakitan akan berjalan secara native pada CPU yang saat ini sedang berjalan. Artinya, itu akan berjalan sebagai 64-bit pada mesin 64-bit dan 32-bit pada mesin 32-bit. Jika rakitan dipanggil dari aplikasi 64-bit, ia akan berfungsi sebagai rakitan 64-bit dan seterusnya.

Tautan di atas telah dilaporkan rusak, jadi di sini ada artikel lain dengan penjelasan yang serupa: Apa Artinya AnyCPU Berarti .NET 4.5 dan Visual Studio 11

DCNYAM
sumber
1
Tautan terputus — pergi ke domain terparkir sekarang.
Jon Adams
Saya menambahkan tautan ke artikel kedua dengan informasi serupa. Saya meninggalkan tautan pertama jika domain tersebut diaktifkan kembali.
DCNYAM
46

Kredit ke buku "CLR via C #" , lihat ini:

Masukkan deskripsi gambar di sini

Ivan
sumber
3
Ini adalah jawaban yang paling akurat pada 09/06/2018 dan VS 15.8.0
Raikol Amaro
39

"Any CPU" berarti bahwa ketika program dimulai, .NET Framework akan mencari tahu, berdasarkan bitness OS, apakah akan menjalankan program Anda dalam 32 bit atau 64 bit.

Ada perbedaan antara x86 dan Any CPU : pada sistem x64, executable Anda yang dikompilasi untuk X86 akan berjalan sebagai executable 32-bit.

Sejauh kecurigaan Anda, cukup buka baris perintah Visual Studio 2008 dan jalankan yang berikut.

dumpbin YourProgram.exe /headers

Ini akan memberi tahu Anda betapa kecilnya program Anda, ditambah lebih banyak lagi.

AngryHacker
sumber
7
Jika itu dibangun di "any cpu", itu akan muncul sebagai 32bit di header dumpbin.
Kirbinator
34

CPU apa pun berarti bahwa itu akan berfungsi pada platform apa pun. Ini karena kode terkelola mirip dengan Java. Anggap saja dikompilasi ke kode byte yang ditafsirkan oleh .NET Framework saat dijalankan.

C ++ tidak memiliki opsi ini karena dikompilasi ke kode mesin yang spesifik platform.

Adam Tegen
sumber
12
+1 untuk menjawab satu bagian dari pertanyaan yang tidak dilakukan orang lain (tentang proyek C ++ tidak memiliki AnyCPU sebagai opsi).
cplotts
C ++ / CLI dapat dikompilasi ke kode IL tanpa kode mesin (/ clr: pure). Tetapi sizeof (void *) masih harus berupa konstanta waktu kompilasi dalam C ++; jadi bahkan ketika tidak ada kode mesin yang terlibat, Anda masih tidak dapat membuat biner yang akan bekerja pada 32-bit dan 64-bit pada saat yang sama.
Daniel
5

Saya merekomendasikan membaca posting ini .

Saat menggunakan AnyCPU , semantiknya adalah sebagai berikut:

  • Jika proses berjalan pada sistem Windows 32-bit, itu berjalan sebagai proses 32-bit. CIL dikompilasi ke kode mesin x86.
  • Jika proses berjalan pada sistem Windows 64-bit, itu berjalan sebagai proses 32-bit. CIL dikompilasi ke kode mesin x86.
  • Jika proses berjalan pada sistem Windows ARM, itu berjalan sebagai proses 32-bit. CIL dikompilasi ke kode mesin ARM.
Mamha
sumber
8
Hanya jika "Lebih suka 32-bit" dipilih.
Florian Winter
Yang merupakan default sejak Visual Studio 11
Moerwald
@ Moellerwald Saya percaya itu adalah bug yang telah diperbaiki. Jika Anda membaca posting yang dibuat oleh mamczas, penulis menulis "di Visual Studio UI saat ini" Prefer 32-bit "berwarna abu-abu dan tidak dicentang, di mana sebenarnya diaktifkan ..."; Dalam versi VS (15.8.0) saya, opsi ini masih berwarna abu-abu dan tidak dicentang, namun berfungsi seperti yang diharapkan (flag 32BITPREF = FALSE di bagian CorFlags perakitan yang dikompilasi)
Raikol Amaro