CorFlags
Narzędzie CorFlags.exe(NET CorFlags Conversion Tool) pozwala na sprawdzenie lub konfiguracje wykonywalnego assembly, tak by było one traktowane jako 64 lub 32 – bitowe. Jest ono instalowane razem z Visual Studio i można z niego skorzystać poprzez np. Visual Studio Command Prompt.Zobaczcie, jaki np. będzie wynik sprawdzenia czy assembly jest 64 lub 32 – bitowe w oparciu o przykład z poprzedniego wpisu.
aplikacja
|
app_anycpu.exe
|
app_x64.exe
|
app_x86.exe
|
Wynik działania: „corflags aplikacja.exe”
|
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 1
ILONLY : 1
32BIT : 0
Signed : 0
|
Version : v2.0.50727
CLR Header: 2.5
PE : PE32+
CorFlags : 1
ILONLY : 1
32BIT : 0
Signed : 0
|
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 3
ILONLY : 1
32BIT : 1
Signed : 0
|
Jak widać, w przypadku aplikacji 64-bitowej narzędzie CorFlags pokazuje, że ustawienie PE (PE=Portable Executable) jest
skonfigurowane jako PE32+. W pozostałych przypadkach PE jest
skonfigurowane jako PE32. Aplikację skonfigurowaną jako „Any CPU”
od aplikacji skonfigurowanej jako aplikacja x86 (32-bit) można
odróżnić poprzez sprawdzenie wartości „CorFlags”, w przypadku
aplikacji „Any CPU” Corlags=1 podczas gdy dla aplikacji x86
Corflags=3.
Narzędzie Corflags potrafi również zmienić konfigurację
assembly. Aby skonfigurować assembly jako aplikację 32-bitową
wystarczy wykonać:
corflags /32bit+ aplikacja
W razie potrzeby ponownego przełączenia na 64 bitowy tryb pracy
używamy następującej składni:
corflags /32bit- aplikacja
IL Disassembler (ILDASM)
Również w IL Disassembler (ILDASM) pozwala na sprawdzenie na jaką
platformę jest skompilowane assembly. Otóż niezależnie od
wybranej platformy docelowej (x86/x64/Any) kod skompilowany z C# (lub
innego języka z platformy .NET) do języka IL będzie wyglądał tak
samo. Assebly będzie się różniło tylko pewnymi wpisami w
manifeście i nagłówku. Poniższy rysunek pokazuje różnice dla
wspomnianych aplikacji.
Jak widać zmianom uległy ustawienia corflags:
- 1 (ILONLY) dla targetów Any i x64,
- 3 (ILONLY 32BITREQUIRED) dla targetu x86
Zmieniony został również nagłówek PE, który w przypadku targetu
x64 jest on 64 bitowy, natomiast 32 bitowy dla pozostałych.
Świetny wpis! Jak ja moglem przeoczyc ten tool wczesniej? ;)
OdpowiedzUsuńm.g.
Ciekawy post. Zastanawia mnie jak wykorzystywana jest informacja o platformie docelowej podczas samego wykonanie kodu. Jedna rzecz to dostęp do komponentów przeznaczonych dla danej platformy, ale czy informacja ta ma znaczenie dla samego sposobu kompilacji JIT? Najdziwniejszą rzeczą jest to, że w swoich aplikacjach zauważyłem, nie zysk, ale spadek w wydajności w przypadku assembly dla platformy x64.
OdpowiedzUsuńPrzepraszam za zwłokę w odpowiedzi.
OdpowiedzUsuńZaak,
Z tego co wiem, to kod z języka wyższego poziomu (np. C#, czy VB.NET) jest kompilowany do IL'a zawsze tak samo (niezależnie od ustawień x86/x64/...) i tak jak napisałem w tym wpisie występują drobne różnie w nagłówkach (głównie w PE).
Na etapie uruchomienia następuje ostatecznie kompilacja do kodu "maszynowego" (just-in-time compilation (JIT)). Więc informacja na temat docelowej platformy ma olbrzymie znaczenie, gdyż uruchamiana jest zupełnie inna platforma (lub wirtualna maszyna - jak kto woli). W systemach Windows x64 najczęściej zainstalowane są różne .NET frameworki - inne dla x64, a inne dla x86. Wystarczy sprawdzić katalogi:
- c:\Windows\Microsoft.NET\Framework
- c:\Windows\Microsoft.NET\Framework64
Przejdźmy do drugiej części pytania. Co do zysku lub straty w wydajności na różnych platformach, to nie jest to taka prosta sprawa, gdyż dużo zależy od samego algorytmu, który jest zaszyty w aplikacji. Należy również sprawdzić wykorzystanie zasobów (np. aplikacja x64 będzie wykorzystywała więcej pamięci RAM i jeżeli pamięci brakuje to będzie wykonywana wolniej). Wydaje się, że aplikacje x86, czy x64 powinny działać podobnie wydajnie, chyba, że kod jest zoptymalizowany na platformę x64 (korzysta z dużych liczb, większej ilości pamięci itp...) i wtedy szybciej powinien być wykonany na platformie x64.