Első kör: C++, Visual Studio 2010, Release fordítás. (O2)
GOTO-val
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
013E1000 push ebp
013E1001 mov ebp,esp
int i = 0;
013E1003 xor eax,eax
if (argc > 4)
013E1005 cmp dword ptr [argc],4
013E1009 jle err+3 (13E100Eh)
goto err;
if (0)
{
err:
i--;
013E100B or eax,0FFFFFFFFh
}
i++;
cout << i;
013E100E mov ecx,dword ptr [__imp_std::cout (13E2048h)]
013E1014 inc eax
013E1015 push eax
013E1016 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (13E2044h)]
return 0;
013E101C xor eax,eax
}
013E101E pop ebp
013E101F ret
Segédváltozóval:
int _tmain(int argc, _TCHAR* argv[])
{
01311000 push ebp
01311001 mov ebp,esp
int i = 0;
01311003 xor eax,eax
bool err = false;
if (argc > 4)
01311005 cmp dword ptr [argc],4
01311009 jle wmain+0Eh (131100Eh)
{
err = true;
}
if (err)
{
i--;
0131100B or eax,0FFFFFFFFh
}
i++;
cout << i;
0131100E mov ecx,dword ptr [__imp_std::cout (1312048h)]
01311014 inc eax
01311015 push eax
01311016 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (1312044h)]
return 0;
0131101C xor eax,eax
}
0131101E pop ebp
0131101F ret
Szóval tökugyanaz. GCC/Clang nem tudom mit csinál, de meglepődnék, ha nem optimalizálna ki egy ilyet.
Na de mi a helyzet .NET-ben?
C#, VS2010, .NET 4.0, Release fordítás
GOTO-val
Error 1 No such label 'err' within the scope of the goto statement c:\users\saxus\documents\visual studio 2010\Projects\ifgoto\ConsoleApplication1\Program.cs 13 17 ConsoleApplication1
;)
Segédváltozóval
var err = false;
00000000 push ebp
00000001 mov ebp,esp
00000003 sub esp,0Ch
00000006 mov dword ptr [ebp-0Ch],ecx
00000009 cmp dword ptr ds:[00670B0Ch],0
00000010 je 00000017
00000012 call 6AF15676
00000017 xor edx,edx
00000019 mov dword ptr [ebp-8],edx
0000001c mov dword ptr [ebp-4],0
00000023 xor edx,edx
00000025 mov dword ptr [ebp-4],edx
var i = 0;
00000028 xor edx,edx
0000002a mov dword ptr [ebp-8],edx
if (args.Length > 4)
0000002d mov eax,dword ptr [ebp-0Ch]
00000030 cmp dword ptr [eax+4],4
00000034 jle 00000043
err = true;
00000036 mov eax,1
0000003b and eax,0FFh
00000040 mov dword ptr [ebp-4],eax
if (err)
00000043 cmp dword ptr [ebp-4],0
00000047 je 0000004C
{
i--;
00000049 dec dword ptr [ebp-8]
}
i++;
0000004c inc dword ptr [ebp-8]
Console.WriteLine(i);
0000004f mov ecx,dword ptr [ebp-8]
00000052 call 6A663F44
}
00000057 nop
00000058 mov esp,ebp
0000005a pop ebp
0000005b ret
.NET 4.5-tel egyébként centire ugyanezt a kódot adja. A helyzetet viszont erősen árnyalja az, hogy a JIT-nek megvan az a képessége, hogy ha látja azt, hogy egy függvényt nagyon sokszor hívunk, akkor nekiáll újraoptimalizálni. Viszont erősen úgy tűnik, hogy nem teszi, még ha végtelen ciklusban futtatom, akkor sem. De az is elképzelhető, hogy erre jelenleg nem készítették fel a .NET jitterét.
tl;dr
Egy jobb C/C++ fordítónál erős az esély, hogy nem számít a segédváltozó, ha statikusan ki lehet értékelni. Más nyelveknél számíthat. Hja és ismételten igaz: ismerni kell a fordítót/VM-et, amit használunk és ne akarjuk okosabbak lenni annál, ha nem muszáj.
- saxus blogja
- A hozzászóláshoz be kell jelentkezni
- 1333 megtekintés
Hozzászólások
Nice.
- A hozzászóláshoz be kell jelentkezni
Thx!
- A hozzászóláshoz be kell jelentkezni
> Viszont erősen úgy tűnik, hogy nem teszi, még ha végtelen ciklusban futtatom, akkor sem.
Ezt mibol latod?
- A hozzászóláshoz be kell jelentkezni
Hagyom futni, aztán teszek egy breakpointot, majd nyomok egy CTRL+ALT+D-t (Dissassembly), hogy lássam, mi fut épp. Feltételezésem szerint, ha a jitter újrafordítaná a kódot, akkor az új függvényt kellene látnom.
Erősen aláhúzva hozzáteszem: szerintem.
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Ha jol emlekszem a CLR via C# konyvben is irja a szerzo hogy a lehetoseg adott hogy futas kozben tobbszor is optimalizaljon a kodon a rendszer, de jelenleg nem teszi.
- A hozzászóláshoz be kell jelentkezni
Na, azt a könyvet elkezdtem már olvasni, de sajna nem volt időm befejezni, pedig kellene.
Azt nem irja, hogy miért?
---------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Ha jol emlekszem nem reszletezte a mierteket.
Szerintem ugy gondoltak a MS-nal hogy igy is kielegito eredmenyt ad a JIT compiler.
Sajnos a felenel en is abbahagytam, eleg suru evem volt. Most meg mar erdemes lenne ujra elorol kezdeni... :)
- A hozzászóláshoz be kell jelentkezni
FYI:
Xi Wang, Nickolai Zeldovich, M. Frans Kaashoek, and Armando Solar-Lezama: Towards Optimization-Safe Systems: Analyzing the Impact of Undefined Behavior
"This paper studies an emerging class of software bugs called optimization-unstable code: code that is unexpectedly discarded by compiler optimizations due to undefined behavior in the program. Unstable code is present in many systems, including the Linux kernel and the Postgres database. The consequences of unstable code range from incorrect functionality to missing security checks. To reason about unstable code, this paper proposes a novel model, which views unstable code in terms of optimizations that leverage undefined behavior. Using this model, we introduce a new static checker called Stack that precisely identifies unstable code. Applying Stack to widely used systems has uncovered 160 new bugs that have been confirmed and fixed by developers"
http://people.csail.mit.edu/nickolai/papers/wang-stack.pdf
Az alabbi teljesen szabalyos C kod pedig nondeterministic:
https://gist.github.com/anonymous/d2e55bb6f735546d9916
- A hozzászóláshoz be kell jelentkezni
C-ben rengeteg ilyen nemdeterminisztikus kod van, ez a fenti pelda eppen abbol van, hogy a + operator operandusaunak kiertekelesenek sorrendje nem definialt a szabvany szintjen, forditofuggo, hogy mi fordul le ezen esetben.
Ez a nyelv hianyossaga, de van meg mas forditofuggo dolog is rendesen.
Ettol fuggetlenul, aki ilyen side effectel rendelkezo kodot ir, az menjen a fenebe.
- A hozzászóláshoz be kell jelentkezni