Visual Studio“ CPU ใด ๆ ” เป้าหมายหมายถึงอะไร


496

ฉันมีความสับสนเกี่ยวกับตัวเลือกการสร้างแพลตฟอร์ม. NET ใน Visual Studio 2008

เป้าหมายการคอมไพล์ "Any CPU" คืออะไรและไฟล์ประเภทใดที่สร้างขึ้น ฉันตรวจสอบเอาต์พุตที่สามารถเรียกใช้งานได้ของ build "CPU ใด ๆ " นี้และพบว่ามันเป็นไฟล์ปฏิบัติการ x86 (ซึ่งไม่เห็นว่าจะมา!) ดังนั้นมีความแตกต่างระหว่างการกำหนดเป้าหมายที่ปฏิบัติการได้เพื่อ x86 กับ "CPU ใด ๆ "

อีกสิ่งที่ฉันสังเกตเห็นคือโครงการ C ++ ที่จัดการไม่มีแพลตฟอร์มนี้เป็นตัวเลือก ทำไมถึงเป็นอย่างนั้น? นั่นหมายความว่าฉันสงสัยเกี่ยวกับโปรแกรมปฏิบัติการ "ใด ๆ CPU" เป็นธรรมดา 32- บิตใช่ไหม?


4
อีกสิ่งหนึ่งที่ควรพิจารณาเมื่อตัดสินใจเลือกแพลตฟอร์มเป้าหมายที่จะใช้: หากเป้าหมายของโครงการเริ่มต้นคือAny CPUและคุณกำลังทำงานบนระบบปฏิบัติการ 64 บิตคุณจะสูญเสียความสามารถในการแก้ไขและดำเนินการต่อในขณะที่การดีบัก (คุณกำลังดีบักกระบวนการ 64 บิตอย่างมีประสิทธิภาพ) คุณสามารถทำให้เป้าหมายโครงการเริ่มต้นx86เพื่อหลีกเลี่ยงปัญหานี้ในขณะที่การดีบัก (ประกอบอ้างอิงจากโครงการเริ่มต้นอาจจะยังคงเป้าหมายAny CPU.
Cristian Diaconescu

8
@CristiDiaconescu ด้วย VS2013 แก้ไขและดำเนินการต่อไปได้ตอนนี้
ms007

ฉันคิดว่าควรมีบันทึกไว้ที่นี่เกี่ยวกับว่าโปรเจ็กต์เป็นแอปพลิเคชั่นหรือไลบรารีคลาสเป็นการกำหนดเป้าหมายให้แก่ผู้ใช้หลังสามารถส่งผลต่อความพร้อมใช้งานของแอปพลิเคชันที่บริโภค ฉันพบกับx86ห้องสมุดที่AnyCPUแอพพลิเคชั่นซึ่งฉันต้องตั้งPrefer 32-bitเพื่อหลีกเลี่ยงข้อผิดพลาดในการโหลด
SteveCinq

คำตอบ:


386

AnyCPUชุมนุมจะ JIT รหัส 64 บิตเมื่อโหลดเข้าสู่กระบวนการแบบ 64 บิตและ 32 บิตเมื่อโหลดลงในกระบวนการแบบ 32 บิต

ด้วยการ จำกัด ซีพียูคุณจะพูดว่า: มีบางอย่างที่ใช้โดยแอสเซมบลี


3
ดังนั้นฉันจะผลิตประกอบซึ่งจะ JIT ถึง x64 ใน C ++ ได้อย่างไร
galets

50
โปรเจ็กต์ C ++ คอมไพล์เป็นรหัสเนทีฟดังนั้นคอมไพเลอร์ JIT ไม่เกี่ยวข้อง ... ดังนั้นคุณไม่สามารถทำสิ่งที่คุณขอได้
cplotts

7
@cplotts: เนื่องจาก @galets ถามคำถามนี้ 3 เดือนที่ผ่านมาไม่น่าจะเห็นคำตอบของคุณ ใช้คำนำหน้า @galets ในความคิดเห็นของคุณคล้ายกับที่ฉันมีที่นี่เพื่อให้เขาได้รับการแจ้งเตือนเกี่ยวกับคำตอบของคุณ
AnthonyWJones

4
@AnthonyWJones โดยทั่วไปคุณถูกต้องยกเว้นว่าผู้ใช้อยู่ตรงไหนของคำถามเช่นเดียวกับในกรณีนี้พวกเขาจะได้รับแจ้งความคิดเห็นทั้งหมด
Mark Hurd

12
@ MarkHurd ที่จริงแล้วในกรณีนี้ OP จะไม่ได้รับการแจ้งเตือน OP ไม่ได้รับการแจ้งเตือนความคิดเห็นต่อคำตอบเว้นแต่ว่าพวกเขาจะถูก ping โดยเฉพาะด้วยไวยากรณ์ @ OP จะได้รับการแจ้งเตือนความคิดเห็นที่เพิ่มในคำถามเดิมโดยอัตโนมัติเท่านั้น
RSW

322

ฉันคิดว่าสิ่งสำคัญส่วนใหญ่ได้รับการกล่าวถึง แต่ฉันคิดว่าฉันจะเพิ่มสิ่งหนึ่ง: ถ้าคุณคอมไพล์เป็นCPU ใด ๆและทำงานบนแพลตฟอร์ม x64 คุณจะไม่สามารถโหลดไฟล์ DLL แบบ 32 บิตได้ เพราะแอปพลิเคชันของคุณไม่ได้เริ่มทำงานในWoW64แต่ไฟล์ DLL เหล่านั้นจำเป็นต้องเปิดใช้ที่นั่น

หากคุณรวบรวมเป็น x86 ระบบ x64 จะเรียกใช้แอปพลิเคชันของคุณใน WoW64 และคุณจะสามารถโหลดไฟล์ DLL 32 บิต

ดังนั้นฉันคิดว่าคุณควรเลือก "CPU ใด ๆ " หากการอ้างอิงของคุณสามารถทำงานในสภาพแวดล้อมใดก็ได้ แต่เลือก x86 ถ้าคุณมีการพึ่งพาแบบ 32 บิต บทความจาก Microsoft นี้อธิบายนี้เล็กน้อย:

/ CLRIMAGETYPE (ระบุประเภทของภาพ CLR)

อนึ่งเอกสารอื่น ๆ ของ Microsoft นี้ยอมรับว่า x86 เป็นตัวเลือกที่พกพาได้มากกว่า:

การเลือก x86 นั้นเป็นการกำหนดค่าที่ปลอดภัยที่สุดสำหรับแพ็คเกจแอพเนื่องจากมันจะทำงานบนอุปกรณ์เกือบทุกชนิด ในบางอุปกรณ์แพคเกจแอปที่มีการกำหนดค่า x86 จะไม่ทำงานเช่น Xbox หรืออุปกรณ์ IoT Core บางตัว อย่างไรก็ตามสำหรับพีซีแพ็คเกจ x86 เป็นตัวเลือกที่ปลอดภัยที่สุดและมีขนาดใหญ่ที่สุดสำหรับการปรับใช้อุปกรณ์ อุปกรณ์ Windows 10 ส่วนใหญ่ยังคงใช้งาน Windows รุ่น x86


2
บางทีคุณสามารถแก้ไขคำตอบของคุณเพื่อบอกว่าใครสามารถตัดสินได้ว่า DLL ที่กำหนดเป็น 32- บิตเท่านั้น เท่าที่ฉันรู้สิ่งนี้น่าจะพอเข้าใจได้ ฉันคิดว่าเราหวังสำหรับ DLLs ที่มี "CPU ใด ๆ " มากกว่า x86 เท่านั้น
Dan W

+1 ความแตกต่างที่สำคัญ จำเป็นต้องใช้การพึ่งพา 32 บิต (ซึ่งไม่ได้ระบุเช่นนั้น) ไม่สามารถหาข้อความแสดงข้อผิดพลาดของ cryptic runtime ได้ บนลางสังหรณ์เปลี่ยนเป้าหมายของซีพียูและใช้งานได้ แต่ไปค้นหา "ทำไม" จะดีสักวันหนึ่งเมื่อทุกอย่างเป็น 64 บิตและปัญหาความไม่ลงรอยกันจะดูแปลกตาเหมือนตอนที่ 16 บิตกับ 32 บิตตอนนี้
เจอรัลด์เดวิสมี. ค.

2
@GeraldDavis - ฉันเห็นด้วย ประชดคือไม่มีเหตุผลทางเทคโนโลยีสำหรับการไม่สามารถผสมการพึ่งพา 32- บิตและ 64- บิต (เพียงขาดเลเยอร์ thunking ใน CLR) และฉันรู้สึกผิดหวังในวันแรกของ. NET เมื่อฉันเห็นบิต - ness ยังคงเป็นสิ่งที่ต้องพิจารณาเมื่อทำการปรับใช้ (การพิจารณาว่านี่เป็น VM / JIT มันจะเป็นโอกาสที่จะสร้างมูลค่าเพิ่มที่เพิ่มขึ้นอีกเล็กน้อย)
codenheim

1
@mrjoltcola: ยิ่งแย่ไปกว่านั้นคือวิธีที่ Microsoft ตัดสินใจด้วยเหตุผลที่ฉันไม่สามารถเข้าใจได้ว่ารายการรีจิสทรีควรแบ่งออกเป็นจักรวาล 32- บิตและ 64- บิตแม้ว่าพวกเขาจะควบคุมสิ่งต่าง ๆ เช่นสีของหน้าจอการตั้งค่าเริ่มต้น ฯลฯ
supercat

นี่คือคำตอบที่ฉันถูกมองหา ... ขอบคุณ!
Murat จาก Daminion Software

52

ต่อไปนี้เป็นภาพรวมโดยย่อที่อธิบายถึงเป้าหมายการสร้างที่แตกต่างกัน

จากประสบการณ์ของฉันเองถ้าคุณต้องการสร้างโครงการที่จะทำงานบนทั้งแพลตฟอร์ม x86 และ x64 และคุณไม่มีการเพิ่มประสิทธิภาพ x64 เฉพาะเจาะจงฉันจะเปลี่ยนโครงสร้างเป็น "x86" โดยเฉพาะ

เหตุผลนี้บางครั้งคุณจะได้รับไฟล์ DLL บางอย่างที่เกิดการชนหรือรหัสบางอย่างที่ทำให้การทำงานล้มเหลวWoWในสภาพแวดล้อม x64 ด้วยการระบุ x86 โดยเฉพาะระบบปฏิบัติการ x64 จะถือว่าแอปพลิเคชันเป็นแอปพลิเคชัน x86 ที่บริสุทธิ์และทำให้แน่ใจว่าทุกอย่างทำงานได้อย่างราบรื่น


37
ซึ่งอาจเป็นเรื่องที่แย่มากหากคุณเขียนให้กับเซิร์ฟเวอร์และต้องการให้แอปพลิเคชันของคุณสามารถใช้หน่วยความจำได้มากกว่า 2GB คุณกำลังยกเลิกการเพิ่มประสิทธิภาพ JIT ใด ๆ ที่อาจเกิดขึ้นในวันนี้
Austin Harris

จำนวนปัญหารันไทม์ที่ฉันเคยมีกับการรวบรวม AnyCPU คือเหตุผลทั้งหมดที่ฉันต้องการเพื่อหยุดการใช้มันเป็นตัวเลือกบิลด์เว้นแต่ว่ามีใครบางคนร้องขอไบนารีที่ทำงานได้อย่างชัดเจน ฉันไม่เคยมีใครขอ x86 ไบนารีมากกว่า x64 เพื่ออะไรในกว่า 10 ปี
kayleeFrye_onDeck

2
"ด้วยการระบุ x86 โดยเฉพาะระบบปฏิบัติการ x64 จะถือว่าแอปเป็นแอพ x86 ที่บริสุทธิ์และทำให้แน่ใจว่าทุกอย่างทำงานได้อย่างราบรื่น" - ขอโทษฉันไม่เห็นด้วย x64 OS จะยังคงใช้งานแอพ x86 ของคุณใน WOW64
Mandeep Janjua

นี่เป็นคำแนะนำที่ไม่ดีสำหรับคนที่ไม่เข้าใจผลกระทบที่จะเกิด @AustinHarris ให้ตัวอย่างที่ดี ลองนึกภาพกระบวนการของผู้ปฏิบัติงานเว็บ จำกัด ให้ RAM เพียงไม่กี่ GB เท่านั้น (เมื่อเร็ว ๆ นี้ฉันต้องจัดการกับเรื่องนี้ในการผลิต)
rgoliveira

47

ตรวจสอบบทความVisual Studio .NET แพลตฟอร์มเป้าหมายอธิบาย

การตั้งค่าเริ่มต้น "CPU ใด ๆ " หมายความว่าแอสเซมบลีจะทำงานโดยกำเนิดบน CPU ที่กำลังทำงานอยู่ ความหมายมันจะทำงานเป็น 64 บิตบนเครื่อง 64 บิตและ 32 บิตบนเครื่อง 32 บิต หากแอสเซมบลีถูกเรียกจากแอปพลิเคชัน 64 บิตแอปพลิเคชันจะทำหน้าที่เป็นแอสเซมบลี 64- บิตและอื่น ๆ

ลิงก์ด้านบนนี้ได้รับการรายงานว่าใช้งานไม่ได้ดังนั้นนี่เป็นอีกบทความที่มีคำอธิบายที่คล้ายกัน: AnyCPU หมายถึงอะไรในฐานะ. NET 4.5 และ Visual Studio 11


1
ลิงก์เสียหาย - ไปที่โดเมนที่พักตอนนี้
Jon Adams

ฉันเพิ่มลิงค์ไปยังบทความที่สองพร้อมข้อมูลที่คล้ายกัน ฉันออกจากลิงก์แรกในกรณีที่โดเมนถูกเปิดใช้งานอีกครั้ง
DCNYAM


39

"CPU ใด ๆ " หมายความว่าเมื่อเริ่มต้นโปรแกรมแล้ว. NET Framework จะคิดตาม OS bitness ไม่ว่าจะรันโปรแกรมของคุณใน 32 บิตหรือ 64 บิต

มีความแตกต่างระหว่างx86และCPU ใด ๆ : บนระบบ x64 ปฏิบัติการที่คุณคอมไพล์สำหรับ X86 จะทำงานเป็นแบบปฏิบัติการได้แบบ 32 บิต

เท่าที่คุณสงสัยไปเพียงไปที่บรรทัดคำสั่ง Visual Studio 2008 และเรียกใช้ต่อไปนี้

dumpbin YourProgram.exe /headers

มันจะบอกคุณเกี่ยวกับโปรแกรมของคุณรวมทั้งอีกมากมาย


7
ถ้ามันถูกสร้างขึ้นใน "ซีพียูใด ๆ " มันจะแสดงเป็น 32 บิตในส่วนหัวของดัลลัส
Kirbinator

34

CPU ใด ๆ หมายความว่ามันจะทำงานบนแพลตฟอร์มใด ๆ นี่เป็นเพราะรหัสที่ได้รับการจัดการคล้ายกับ Java คิดว่ามันถูกรวบรวมเป็นรหัสไบต์ที่ตีความโดย. NET Framework ในเวลาทำงาน

C ++ ไม่มีตัวเลือกนี้เนื่องจากถูกคอมไพล์ไปยังรหัสเครื่องที่เป็นแพลตฟอร์มเฉพาะ


12
+1 สำหรับการตอบคำถามส่วนหนึ่งที่ไม่มีใครทำ (ประมาณโครงการ C ++ ที่ไม่มีตัวเลือก AnyCPU)
cplotts

สามารถรวบรวม C ++ / CLI เป็นรหัส IL ได้โดยไม่ต้องมีรหัสเครื่องใด ๆ (/ clr: pure) แต่ sizeof (void *) ยังคงต้องมีค่าคงที่เวลาคอมไพล์ใน C ++; ดังนั้นแม้ว่าจะไม่มีรหัสเครื่องที่เกี่ยวข้องคุณก็ยังไม่สามารถสร้างไบนารีที่จะทำงานกับ 32 บิตและ 64 บิตในเวลาเดียวกัน
แดเนียล

5

ฉันแนะนำให้อ่านโพสต์นี้

เมื่อใช้AnyCPUความหมายมีดังต่อไปนี้:

  • หากกระบวนการทำงานบนระบบ Windows แบบ 32 บิตกระบวนการนั้นจะทำงานแบบกระบวนการแบบ 32 บิต CILถูกคอมไพล์เป็นรหัสเครื่อง x86
  • หากกระบวนการทำงานบนระบบ Windows 64 บิตกระบวนการนั้นจะทำงานเป็นกระบวนการแบบ 32 บิต CIL ถูกคอมไพล์เป็นรหัสเครื่อง x86
  • หากกระบวนการทำงานบนระบบ ARM Windows จะทำงานเป็นกระบวนการแบบ 32 บิต CIL ถูกคอมไพล์เป็นรหัสเครื่อง ARM

8
เฉพาะเมื่อเลือก "Prefer 32- บิต" เท่านั้น
Florian Winter

ซึ่งเป็นค่าเริ่มต้นตั้งแต่ Visual Studio 11
Moerwald

@ Moerwald ฉันเชื่อว่าเป็นข้อผิดพลาดที่ได้รับการแก้ไข หากคุณอ่าน โพสต์ mamczas อ้างอิงถึงผู้เขียนเขียน "ใน Visual Studio UI ปัจจุบัน" ชอบ 32 บิต "จะเป็นสีเทาและไม่ถูกตรวจสอบโดยที่เปิดใช้งานจริง ... "; ในรุ่นของฉัน VS (15.8.0) ตัวเลือกที่เป็นสีเทายังคงออกและไม่ได้ตรวจสอบ แต่ก็ทำงานได้ตามที่คาดไว้ (ธง 32BITPREF = false ในการรวบรวมการชุมนุมของส่วน CorFlags)
Raikol อามาโร่

-1

นี่คือวิธีที่ฉันทำใน Visual Studio 2017:

  • ใน Solution explorer
  • คลิกขวาที่โครงการของคุณ
  • คลิกที่ "คุณสมบัติ"
  • คลิกที่ "สร้าง"
  • ปิดตัวเลือก "ต้องการ 32 บิต"
  • และคุณสามารถเลือก "x64" จากเป้าหมายแพลตฟอร์ม

คำตอบนี้อยู่นอกหัวข้อ
Jonas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.