🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: alt.pl.comp.lang.csharp
2 messages
2 total messages Started by Paweł Sun, 06 May 2012 13:17
optymalizacje kodu / aot.
#22393
Author: 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?
Re: optymalizacje kodu / aot.
#22394
Author: krlm.usenet
Date: Thu, 10 May 2012 11:07
14 lines
1747 bytes
W dniu niedziela, 6 maja 2012 15:17:59 UTC+2 użytkownik Paweł napisał:
> witam,

> 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?

Strzelam, ze problem stanowi array bound check. Rzuc okiem tutaj:
http://www.mono-project.com/Mono:Runtime:Documentation:LLVM#Array_Bounds_Check_.28ABC.29_elimination

-- 
Pozdrawiam, 
Marcin Kral
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads