czwartek, 14 kwietnia 2011

Sprawdzamy platformę, na jaką zostało skompilowane assembly, czyli zamieszania z Any CPU, x86, x64 w .NET ciąg dalszy [PL]

W poprzednim wpisie pojawiły się informacje na temat sposobów skompilowania assembly, tak by działała jako kod 64 lub 32 –bitowy. W tym wpisie znajdą się informacje na temat tego jak można sprawdzić, na jaką platformę zostało skompilowane assembly (czyli znajdą się tu m.in. informacje na temat narzędzia CorFlags, IL Disassembler'a).

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.
Promuj

3 komentarze:

  1. Świetny wpis! Jak ja moglem przeoczyc ten tool wczesniej? ;)

    m.g.

    OdpowiedzUsuń
  2. 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ń
  3. Przepraszam za zwłokę w odpowiedzi.

    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.

    OdpowiedzUsuń

Posty powiązane / Related posts