🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: alt.pl.comp.lang.csharp
Article #22393

optymalizacje kodu / aot.

#22393
From: Paweł
Date: Sun, 06 May 2012 13:17
117 lines
5616 bytes
witam,

przymierzam sie do przyuczenia c# (po latach spedzonych w c++) i tak sobie
ogladam jaki kod produkuje / jak optymalizuje mono. to co widze nie napawa
mnie optymizmem w kontekscie pozniejszej wydajnosci, ale moze sie myle.
oto przyklad:

class test
{
	struct Simple
	{
		public int i { get; set; }
		public int j { get; set; }
	}

	static void Main( string[] args )
	{
		Simple[] sa = new Simple[ 1 ];
		sa[ 0 ].i = 7;
		sa[ 0 ].j = 3;
		int x = sa[ 0 ].i + sa[ 0 ].j;
		System.Console.WriteLine( x );
	}
}

jak widac, mamy tu wielokrotny dostep do tego samego elementu
tablicy, ktory wiekszosc kompilatorow c/c++ w ramach tzw. CSE
ladnie optymalizuje wyliczajac sobie tylko raz adres wybranej
komorki tablicy, ale w przypadku c# widze:

$ mcs -optimize+ test.cs            
$ monodis test.exe                  

    // method line 1
    .method private static hidebysig 
           default void Main (string[] args)  cil managed 
    {
        // Method begins at RVA 0x2050
        .entrypoint
        // Code size 66 (0x42)
        .maxstack 3
        .locals init (
                valuetype test/Simple[] V_0,
                int32   V_1)
        IL_0000:  ldc.i4.1 
        IL_0001:  newarr test/Simple
        IL_0006:  stloc.0 
        IL_0007:  ldloc.0 
        IL_0008:  ldc.i4.0 
        IL_0009:  ldelema test/Simple
        IL_000e:  ldc.i4.7 
        IL_000f:  call instance void valuetype test/Simple::set_i(int32)
        IL_0014:  ldloc.0 
        IL_0015:  ldc.i4.0 
        IL_0016:  ldelema test/Simple
        IL_001b:  ldc.i4.3 
        IL_001c:  call instance void valuetype test/Simple::set_j(int32)
        IL_0021:  ldloc.0 
        IL_0022:  ldc.i4.0 
        IL_0023:  ldelema test/Simple
        IL_0028:  call instance int32 valuetype test/Simple::get_i()
        IL_002d:  ldloc.0 
        IL_002e:  ldc.i4.0 
        IL_002f:  ldelema test/Simple
        IL_0034:  call instance int32 valuetype test/Simple::get_j()
        IL_0039:  add 
        IL_003a:  stloc.1 
        IL_003b:  ldloc.1 
        IL_003c:  call void class [mscorlib]System.Console::WriteLine(int32)
        IL_0041:  ret 
    } // end of method test::Main

na poziomie zoptymalizowanego bajtkodu 4x ladowanie namiarow + "call",
to juz nie wyglada rozowo. sprawdzilem wiec wersje prekompilowana do
kodu maszynowego:

$ mono --aot --optimize=all test.exe

0000000000001010 <test_Main_string__>:
    1010:       48 83 ec 08             sub    $0x8,%rsp
    1014:       49 8b 3d 0d 25 00 00    mov    0x250d(%rip),%rdi        # 3528 <__bss_start+0x18>
    101b:       be 01 00 00 00          mov    $0x1,%esi
    1020:       e8 2b 01 00 00          callq  1150 <plt__jit_icall_mono_array_new_specific>
    1025:       48 8b c8                mov    %rax,%rcx
    1028:       33 d2                   xor    %edx,%edx
    102a:       48 63 d2                movslq %edx,%rdx
    102d:       39 51 18                cmp    %edx,0x18(%rcx)
    1030:       0f 86 7b 00 00 00       jbe    10b1 <test_Main_string__+0xa1>
    1036:       48 8d 4c d1 20          lea    0x20(%rcx,%rdx,8),%rcx
    103b:       c7 01 07 00 00 00       movl   $0x7,(%rcx)
    1041:       33 c9                   xor    %ecx,%ecx
    1043:       48 63 c9                movslq %ecx,%rcx
    1046:       39 48 18                cmp    %ecx,0x18(%rax)
    1049:       0f 86 5b 00 00 00       jbe    10aa <test_Main_string__+0x9a>
    104f:       48 8d 4c c8 20          lea    0x20(%rax,%rcx,8),%rcx
    1054:       c7 41 04 03 00 00 00    movl   $0x3,0x4(%rcx)
    105b:       33 c9                   xor    %ecx,%ecx
    105d:       48 63 c9                movslq %ecx,%rcx
    1060:       39 48 18                cmp    %ecx,0x18(%rax)
    1063:       0f 86 3a 00 00 00       jbe    10a3 <test_Main_string__+0x93>
    1069:       48 8d 4c c8 20          lea    0x20(%rax,%rcx,8),%rcx
    106e:       48 63 39                movslq (%rcx),%rdi
    1071:       33 c9                   xor    %ecx,%ecx
    1073:       48 63 c9                movslq %ecx,%rcx
    1076:       39 48 18                cmp    %ecx,0x18(%rax)
    1079:       0f 86 15 00 00 00       jbe    1094 <test_Main_string__+0x84>
    107f:       48 8d 44 c8 20          lea    0x20(%rax,%rcx,8),%rax
    1084:       48 63 40 04             movslq 0x4(%rax),%rax
    1088:       03 f8                   add    %eax,%edi
    108a:       e8 cb 00 00 00          callq  115a <plt_System_Console_WriteLine_int>
    108f:       48 83 c4 08             add    $0x8,%rsp
    1093:       c3                      retq

no i tez szalu nie ma. raptem przypisanie dwoch slow i ich odczytanie,
a taka sieczka. czy powinienem uzyc jakis specjalnych opcji mono,
zeby to bylo efektywne, a moze operator [] tablic ma jakies wlasciwosci,
ktore nie pozwalaja na optymalizacje tego typu dostepu?
Technical Details
Message-ID: <jo5tm7$vuo$1@news.icm.edu.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!.POSTED!not-for-mail

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!.POSTED!not-for-mail
From: Paweł <root@127.0.0.1>
Newsgroups: alt.pl.comp.lang.csharp
Subject: optymalizacje kodu / aot.
Date: Sun, 06 May 2012 15:17:59 +0200
Organization: ICM, Uniwersytet Warszawski
Lines: 118
Message-ID: <jo5tm7$vuo$1@news.icm.edu.pl>
NNTP-Posting-Host: 89-78-237-144.dynamic.chello.pl
Mime-Version: 1.0
X-Trace: news.icm.edu.pl 1336310279 32728 89.78.237.144 (6 May 2012 13:17:59 GMT)
X-Complaints-To: usenet@news.icm.edu.pl
NNTP-Posting-Date: Sun, 6 May 2012 13:17:59 +0000 (UTC)
User-Agent: KNode/4.8.3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit