À quoi sert le paramètre «Préférer 32 bits» dans Visual Studio et comment fonctionne-t-il réellement?

204

Entrez la description de l'image ici

Il n'est pas clair pour moi comment le compilateur saura automatiquement compiler pour 64 bits quand il en aura besoin. Comment sait-il quand il peut cibler en toute confiance 32 bits?

Je suis principalement curieux de savoir comment le compilateur sait quelle architecture cibler lors de la compilation. Analyse-t-il le code et prend-il une décision en fonction de ce qu'il trouve?

Aaron
la source
Ah merci. Je n'ai pas vu ça avant. Je suis toujours curieux de savoir comment le compilateur sait automatiquement quelle architecture cibler. Des idées?
Aaron

Réponses:

219

Microsoft a une entrée de blog ce que AnyCPU signifie vraiment comme .NET 4.5 et Visual Studio 11 :

Dans .NET 4.5 et Visual Studio 11, le fromage a été déplacé. La valeur par défaut pour la plupart des projets .NET est à nouveau AnyCPU, mais il y a plus d'une signification pour AnyCPU maintenant. Il existe un sous-type supplémentaire d'AnyCPU, «Any CPU 32-bit Preferred», qui est la nouvelle valeur par défaut (dans l'ensemble, il y a maintenant cinq options pour le commutateur du compilateur / platform C #: x86, Itanium, x64, anycpu et anycpu32bitpreferred ). Lorsque vous utilisez la saveur "Préférer 32 bits" d'AnyCPU, la sémantique est la suivante:

  • Si le processus s'exécute sur un système Windows 32 bits, il s'exécute en tant que processus 32 bits. IL est compilé en code machine x86.
  • Si le processus s'exécute sur un système Windows 64 bits, il s'exécute en tant que processus 32 bits. IL est compilé en code machine x86.
  • Si le processus s'exécute sur un système Windows ARM, il s'exécute en tant que processus 32 bits. IL est compilé en code machine ARM.

La différence entre «Any CPU 32-bit Preferred» et «x86» est seulement la suivante: une application .NET compilée en x86 ne fonctionnera pas sur un système Windows ARM, mais une application «Any CPU 32-bit Preferred» fonctionnera avec succès.

Lex Li
la source
12
+1. En outre, la case à cocher "Préférer 32 bits" n'est activée que pour les projets exécutables .NET 4.5+.
Lee Grissom
12
Un autre avantage de anycpu32bitspreferred est qu'un autre .exe exécuté en 64 bits peut charger cet assembly.
Bruno Martinez
30
Personnellement, je pense que c'est horrible, ils l'ont défini par défaut sans aucun paramètre Tools pour le désactiver. Pire encore, vous ne pouvez pas le rechercher car il ne se trouve pas dans les fichiers csproj sauf s'il est désactivé! Probablement ajouté en raison des incompatibilités d'Office Automation avec CPUAny sur une machine x64 avec la plupart des gens installant Office 32 bits.
Dave
6
@BrianDavidBerman il y a, si vous définissez false sur 32 mais préféré et définissez x64 ou Any CPU sur une machine 64 bits.
Lex Li
6
La différence entre x86 et Any CPU 32 bit préféré est que dans ce dernier cas, l'indicateur de détection de grande largeur est défini sur l'exécutable. Cela signifie que le processus 32 bits exécuté sur un système d'exploitation 64 bits peut utiliser 2 Go de mémoire en mode x86 et 4 Go de mémoire en mode préféré Any CPU 32 bits.
Nic
6

Voici une réponse simple:

Arc d'application.

Remarque: AnyCPU-32bitPreferred n'est disponible que dans .Net version 4.5 et supérieure.

Yousha Aleayoub
la source
2
Quelle est la différence entre "s'exécute en 32 bits" et s'exécute en "WoW64". Je pensais que WoW64 = "Windows (32 bits) sur Windows64" et était nécessaire à l'exécution de n'importe quelle application 32 bits.
Peter Cordes du
Y a-t-il une source à cela? Apparemment, partout ailleurs, la valeur par défaut est anycpu32bitpreferred, ce qui est une grande différence pour les personnes exécutant des machines Windows 64 bits (c'est beaucoup).
Ran Sagy
@RanSagy vous pouvez simplement le tester en créant un nouveau projet et en le vérifiant Project -> Properties -> Build tab -> Platform target... mais notez qu'il AnyCPU-32bitPreferredest uniquement disponible dans .Net version 4.5 et supérieure. C'est pourquoi la valeur par défaut est AnyCPU.
Yousha Aleayoub
Dans certains cas, le mien était grisé; J'espérais juste qu'il y ait de la documentation sur ce qui se passe dans .net 4.5+ ou .net standard / core (ou vraiment, MSBuild 16)
Ran Sagy
-1

La raison en est: au cas où vous ne voudriez pas utiliser plus de mémoire avec des applications 64 bits. Ce qui signifie, si votre application est AnyCPU , vous souhaitez l'exécuter en 32 bits.

Pour en ajouter plus, le paramètre dans Visual Studio cible le CLR particulier:

Visual Studio installe la version 32 bits du CLR sur un ordinateur x86, ainsi que la version 32 bits et la version 64 bits appropriée du CLR sur un ordinateur Windows 64 bits. (Étant donné que Visual Studio est une application 32 bits, lorsqu'elle est installée sur un système 64 bits, elle s'exécute sous WOW64.)

Veuillez vous référer à l'article Applications 64 bits ( MSDN ).

Pérou
la source
1
Je ne suis pas sûr que ce soit exact. En tant que, je crois comprendre que les exécutables .NET indépendamment de 32 ou 64 sont toujours limités à environ 2 Go par processus.
JP Richardson
1
Modifié ma réponse. Mais je ne sais pas si c'est ce que vous cherchez :)
Pérou
2
@Aaron, le compilateur définit essentiellement l'indicateur pour l'exécution pour décider s'il est correct de charger l'assembly (c'est-à-dire bloquer l'assembly x86 uniquement à charger dans le processus x64) et comment démarrer le processus (pour le nouvel EXE) en fonction des indicateurs. Je crois que l'IL est le même pour les deux saveurs.
Alexei Levenkov
1
@JPRichardson Oui, vous avez raison. Mais dans .net 4.5, vous avez la possibilité d'augmenter la taille. voir MSDN
Pérou
40
@JPRichardson, ni exécutable .32 ni 64 bits .Net limité à 2 Go par processus - tout d'abord l'espace d'adressage par processus est une restriction au niveau du système d'exploitation (2/3 + Go pour le processus 32 bits et bien plus pour 64 bits), la deuxième version même 32 bits peut utilisez plus de 2 Go si l'indicateur "LargeAddressAware" est défini sur l'exécutable. Les seules restrictions de 2 Go que je connais concernent les tailles de baie / d'allocation qui sont limitées par la plage Int32 (environ 2 Go).
Alexei Levenkov