GCC optimalizace pro různé ISA

mhi

  • *****
  • 500
    • Zobrazit profil
GCC optimalizace pro různé ISA
« kdy: 23. 10. 2021, 22:47:53 »
Resim aktualne takovy problem, jehoz vystup asi uplne nepotesi priznivce RISC-V ekosystemu (nebo ukaze nejakou moji  neznalost). Pomoci velmi podmineneho prekladu s gcc ( -Os )  vytvarim 'code snippety', ktere nasledne nejaky automat bude skladat za sebe (jde o dynamicky translator). Protoze chci zjistit, jestli to bude pouzitelne i jinde nez v x86 svete, nasbiral jsem ruzne prekladace a zkusil tyto code snippety vygenerovat pro ruzne architektury. Zde je vysledek; pocet vygenerovanych instrukci pro nejakou sadu tech snippetu; cim nizsi, tim kratsi kod. CISC je zde zvyhodnen, protoze instrukce hlavne u x86_64 jsou mnohem delsi nez jinde, hlavne u ARM (thumb2). Co jsem zkoumal vystup, obvykle vic instrukci rovna se i vyrazne mene optimalni kod a zbytecne zonglovani s daty.

Kód: [Vybrat]
  10527 report-arm-noflags.txt  (thumb2)
  10938 report-armv8-noflags.txt
  11209 report-x64-noflags.txt
  12311 report-ppc32-noflags.txt
  12371 report-sparc64-noflags.txt
  12809 report-xtensa-noflags.txt
  13036 report-x86-noflags.txt
  14718 report-mips32-noflags.txt
  16903 report-rv32-noflags.txt
  18407 report-rv64-noflags.txt

Mam jeste jednu sadu, kde se vyhodnocuji nejake operace, to pridava ale do vetsiny snippetu  celkem dost podobneho kodu, ktery by sel resit za pouziti flagu (cf/of/if) kdyby to gcc umelo lepe (typicky pushf a pozdeji v kodu popf pro nasledne snadne zpracovani ruznych overflow/carry/apod.). Spis jen pro priklad vlozim i to:

Kód: [Vybrat]
  13151 report-x64-flags.txt
  13225 report-arm-flags.txt
  15175 report-ppc32-flags.txt
  15535 report-x86-flags.txt
  15770 report-sparc64-flags.txt
  17118 report-xtensa-flags.txt
  22410 report-rv32-flags.txt
  23900 report-rv64-flags.txt

Krome RV64 a mam i realne zelezo, tak mohu porovnat i vysledky v rychlosti, nejak upravene na nejake MHz procesoru (xtensa je ESP32 LX6, tezko srovnavat primo s PowerPC nebo x86 dospelym pocitacem).

Nicmene mam i otazku. GCC mi generuje kod, ve kterem se skace a rutina nekonci nejakym "ret/blr", priklad (ppc32):

Kód: [Vybrat]
   0: 94 21 ff e0 stwu    r1,-32(r1)
   4: 7c 08 02 a6 mflr    r0
   8: 90 01 00 24 stw     r0,36(r1)
   c: 93 e1 00 1c stw     r31,28(r1)
..
  48: 7d 4a 40 39 and.    r10,r10,r8
  4c: 41 82 00 18 beq     64
  50: 48 00 00 01 bl      50
50: R_PPC_REL24 spec_read
  54: 7c 7f 1a 14 add     r3,r31,r3
  58: 98 7d 00 00 stb     r3,0(r29)
  5c: 39 61 00 20 addi    r11,r1,32
[b]  60: 48 00 00 00 b       60 <exec86+0x60>
60: R_PPC_REL24 _restgpr_31_x   (!!!)[/b]
  64: 81 3d 00 2c lwz     r9,44(r29)
  68: 7c 69 18 ae lbzx    r3,r9,r3
[b]  6c: 4b ff ff e8 b       54 [/b]

Na adrese 60 je netypicke ukonceni (dusledek -Os), kazdopadne i kdyby tam bylo blr, nekonci tim rutina. Ja bych potreboval, abych z konce rutiny (0x6c) mohl jen odriznout blr a nebyl tam nejaky odskok "nahoru". A tim by slo trivialne retezit snippety za sebe v dynamicky generovanem kodu. Tusite jak k necemu takovemu primet gcc? Nedela to jen na powerpc, ale i jinych architekturach, typicky ARM. Reseni by bylo "linearizovat" kod, aby sel odshora dolu, a neskakal si nekam vzhuru. Jenze to musim naprogramovat. Dale bych uvital, kdybych nejak prekladaci umel rici, aby se treba vyvaroval nejakeho konstruktu, treba nejake relokaci, apod. Diky za pripadne tipy.

Prekvapenim je RISC-V, ktery ciselne, ale i pohledove generuje pomerne sileny kod. Tam, kde ma ARM uz spocitano, se risc-v potaci nekde v tom jak vidlemi prehazovat data... registru ma pritom mnohem vic RISC-V.
« Poslední změna: 24. 10. 2021, 16:29:09 od Petr Krčmář »


RDa

  • *****
  • 2 487
    • Zobrazit profil
    • E-mail
Re:GCC optimalizace pro ruzne ISA
« Odpověď #1 kdy: 24. 10. 2021, 00:26:31 »
Reseni by bylo "linearizovat" kod, aby sel odshora dolu, a neskakal si nekam vzhuru. Jenze to musim naprogramovat.

Tak jde prece jenom o nejaky relative jump na konec snippetu ne? :)
Tj. mala editace adresy.. ale napsat match na ten exit op bude asi tezky.

Re:GCC optimalizace pro ruzne ISA
« Odpověď #2 kdy: 24. 10. 2021, 13:50:39 »
-O0 a -Os na GCC produkuje velmi špatnej RV kód, porovnej s -O2 nebo -O3 a bude tam toho házení vidlema podstatně míň (a výstup bude paradoxně kratší než s -Os).

mhi

  • *****
  • 500
    • Zobrazit profil
Re:GCC optimalizace pro různé ISA
« Odpověď #3 kdy: 24. 10. 2021, 19:13:51 »
RDa: pro RISC neni az tak velky problem napsat ten tool, ktery to reorganizuje. Tim ten koncovy blr/ret/jmp/jb/... vzdy "vypadne", resp. bude se s nim dat snadno pracovat.

KS: Pokud na -Os zpravidla generuje vetsi kod nez na -O2/3, tak je toolchain z meho pohledu rozbity. Vyzkousel jsem to, skutecne je kod mensi, ale stale jsme na cislech, ktera jsou neprijatelna:

   16695 report-rv32-noflags-O2.txt
   16903 report-rv32-noflags-O3.txt  (!pocet instrukci stejny jak -Os, ale je to jen nejaka nahoda, kod se lisi)

Ve vysledku uz je zahrnuta nejaka rucni optimalizace C kodu, kterou jsem v mezidobi udelal, na puvodnim kodu by to bylo horsi.

Pro srovnani, arm a x86 jsou na tom nyni takto:

    8999 report-arm-noflags.txt  thumb2
   10715 report.txt   toto je X86 noflags, pozor nektere instrukce jsou dost dlouhe

Navyseni velikosti kodu o > 70% znamena, ze i kdyz budu mit stejne efektivni CPU, musim mit treba o 70% vice cache, aby byl stejny vysledek u RISC-V. Navic ma rv32 spousti instrukci 32bitovych, proti arm-thumb2, kde jich je radove mene. x86 ma prumer tak 3-4 byty/instr. Je to pro mne celkem zklamani, na to jak tu nekteri aktualni stav teto ISA obhajuji.
« Poslední změna: 24. 10. 2021, 19:21:42 od mhi »

RDa

  • *****
  • 2 487
    • Zobrazit profil
    • E-mail
Re:GCC optimalizace pro různé ISA
« Odpověď #4 kdy: 24. 10. 2021, 21:19:10 »
Navyseni velikosti kodu o > 70% znamena, ze i kdyz budu mit stejne efektivni CPU, musim mit treba o 70% vice cache, aby byl stejny vysledek u RISC-V. Navic ma rv32 spousti instrukci 32bitovych, proti arm-thumb2, kde jich je radove mene. x86 ma prumer tak 3-4 byty/instr. Je to pro mne celkem zklamani, na to jak tu nekteri aktualni stav teto ISA obhajuji.

Nema RV32 a RV64 fixni velikost instrukce typu 4B*N a 8B*N ? Treba u PPC me hodne prekvapilo (po x86 svete), ze instrukce jsou stejne dlouhe, kdyz jsem videl nejaky disassembly report.

Muzes dat nejaky priklad jednoducheho snippetu, jak vypada na x86/x64, arm/aarch4 a na RV32/RV64 v disasm tvaru?


Re:GCC optimalizace pro různé ISA
« Odpověď #5 kdy: 24. 10. 2021, 23:48:37 »
Zajímavé hraní :-) paradoxně mi tu RV64 vychází jako nejkratší. Krátká aritmetická funkce:

Kód: [Vybrat]
fn is_prime(n: u32) bool {
    var i: u32 = 2;

    while (i <= n / 2) {
        if (n % i == 0) {
            return false;
        }

        i += 1;
    }

    return true;
}

Chvíli jsem musel přemýšlet, protože v jednoduchém programu, kdy jen funkci zavolám z mainu s nějakým parametrem, mi Zig během kompilace dokázal, že jsou všechny argumenty známé a tak funkci vůbec nezkompiloval, rovnou dosadil výsledek :-)

RV32 mi chybí, ve standardní knihovně není implementace jednoho syscallu.

zig build-exe -O ReleaseSmall main.zig:
Kód: [Vybrat]
0000000000208c36 <is_prime>:
  208c36: 89 f9                         mov     ecx, edi
  208c38: d1 e9                         shr     ecx
  208c3a: 6a 02                         push    2
  208c3c: 58                            pop     rax
  208c3d: 89 c6                         mov     esi, eax
  208c3f: 39 c8                         cmp     eax, ecx
  208c41: 77 0d                         ja      0x208c50 <is_prime+0x1a>
  208c43: 89 f8                         mov     eax, edi
  208c45: 31 d2                         xor     edx, edx
  208c47: f7 f6                         div     esi
  208c49: 8d 46 01                      lea     eax, [rsi + 1]
  208c4c: 85 d2                         test    edx, edx
  208c4e: 75 ed                         jne     0x208c3d <is_prime+0x7>
  208c50: 39 ce                         cmp     esi, ecx
  208c52: 0f 97 c0                      seta    al
  208c55: c3                            ret

zig build-exe -O ReleaseSmall main.zig -target i386-linux:
Kód: [Vybrat]
004087b1 <is_prime>:
  4087b1: 57                            push    edi
  4087b2: 56                            push    esi
  4087b3: 89 ce                         mov     esi, ecx
  4087b5: d1 ee                         shr     esi
  4087b7: 6a 02                         push    2
  4087b9: 58                            pop     eax
  4087ba: 89 c7                         mov     edi, eax
  4087bc: 39 f0                         cmp     eax, esi
  4087be: 77 0d                         ja      0x4087cd <is_prime+0x1c>
  4087c0: 89 c8                         mov     eax, ecx
  4087c2: 31 d2                         xor     edx, edx
  4087c4: f7 f7                         div     edi
  4087c6: 8d 47 01                      lea     eax, [edi + 1]
  4087c9: 85 d2                         test    edx, edx
  4087cb: 75 ed                         jne     0x4087ba <is_prime+0x9>
  4087cd: 39 f7                         cmp     edi, esi
  4087cf: 0f 97 c0                      seta    al
  4087d2: 5e                            pop     esi
  4087d3: 5f                            pop     edi
  4087d4: c3                            ret

zig build-exe -O ReleaseSmall main.zig -target arm-linux:
Kód: [Vybrat]
00028100 <is_prime>:
   28100: 70 40 2d e9   push    {r4, r5, r6, lr}
   28104: 00 40 a0 e1   mov     r4, r0
   28108: a0 60 a0 e1   lsr     r6, r0, #1
   2810c: 02 10 a0 e3   mov     r1, #2
   28110: 01 50 a0 e1   mov     r5, r1
   28114: 06 00 51 e1   cmp     r1, r6
   28118: 05 00 00 8a   bhi     0x28134 <is_prime+0x34> @ imm = #20
   2811c: 04 00 a0 e1   mov     r0, r4
   28120: 05 10 a0 e1   mov     r1, r5
   28124: eb 02 00 eb   bl      0x28cd8 <__umodsi3>     @ imm = #2988
   28128: 01 10 85 e2   add     r1, r5, #1
   2812c: 00 00 50 e3   cmp     r0, #0
   28130: f6 ff ff 1a   bne     0x28110 <is_prime+0x10> @ imm = #-40
   28134: 00 00 a0 e3   mov     r0, #0
   28138: 06 00 55 e1   cmp     r5, r6
   2813c: 01 00 00 83   movwhi  r0, #1
   28140: 70 80 bd e8   pop     {r4, r5, r6, pc}

zig build-exe -O ReleaseSmall main.zig -target aarch64-linux:
Kód: [Vybrat]
0000000000216a94 <is_prime>:
  216a94: 08 7c 01 53   lsr     w8, w0, #1
  216a98: 4a 00 80 52   mov     w10, #2
  216a9c: e9 03 0a 2a   mov     w9, w10
  216aa0: 5f 01 08 6b   cmp     w10, w8
  216aa4: a8 00 00 54   b.hi    0x216ab8 <is_prime+0x24>
  216aa8: 0a 08 c9 1a   udiv    w10, w0, w9
  216aac: 4b 81 09 1b   msub    w11, w10, w9, w0
  216ab0: 2a 05 00 11   add     w10, w9, #1             // =1
  216ab4: 4b ff ff 35   cbnz    w11, 0x216a9c <is_prime+0x8>
  216ab8: 3f 01 08 6b   cmp     w9, w8
  216abc: e0 97 9f 1a   cset    w0, hi
  216ac0: c0 03 5f d6   ret

zig build-exe -O ReleaseSmall main.zig -target riscv64-linux:
Kód: [Vybrat]
000000000001778c <is_prime>:
   1778c: 9b 55 15 00   srliw   a1, a0, 1
   17790: 09 46         addi    a2, zero, 2
   17792: 9b 06 06 00   sext.w  a3, a2
   17796: 63 e6 d5 00   bltu    a1, a3, 0x177a2 <is_prime+0x16>
   1779a: 3b 77 c5 02   remuw   a4, a0, a2
   1779e: 05 06         addi    a2, a2, 1
   177a0: 6d fb         bnez    a4, 0x17792 <is_prime+0x6>
   177a2: 33 b5 d5 00   sltu    a0, a1, a3
   177a6: 82 80         ret

zig build-exe -O ReleaseSmall main.zig -target powerpc-linux:
Kód: [Vybrat]
10018e9c <is_prime>:
10018e9c: 54 64 f8 7e   srwi 4, 3, 1
10018ea0: 38 c4 00 01   addi 6, 4, 1
10018ea4: 38 a0 00 02   li 5, 2
10018ea8: 28 06 00 02   cmplwi  6, 2
10018eac: 41 81 00 0c   bt      1, 0x10018eb8
10018eb0: 60 a6 00 00   ori 6, 5, 0
10018eb4: 48 00 00 04   b 0x10018eb8
10018eb8: 38 c6 ff ff   addi 6, 6, -1
10018ebc: 7c c9 03 a6   mtctr 6
10018ec0: 7c a6 2b 78   mr      6, 5
10018ec4: 42 40 00 18   bdz 0x10018edc
10018ec8: 7c a3 33 96   divwu 5, 3, 6
10018ecc: 7c a5 31 d6   mullw 5, 5, 6
10018ed0: 7c a5 18 51   sub.    5, 3, 5
10018ed4: 38 a6 00 01   addi 5, 6, 1
10018ed8: 40 82 ff e8   bf      2, 0x10018ec0
10018edc: 7c 06 20 40   cmplw   6, 4
10018ee0: 38 60 00 00   li 3, 0
10018ee4: 38 80 00 01   li 4, 1
10018ee8: 41 81 00 08   bt      1, 0x10018ef0
10018eec: 4e 80 00 20   blr
10018ef0: 38 64 00 00   addi 3, 4, 0
10018ef4: 4e 80 00 20   blr

zig build-exe -O ReleaseSmall main.zig -target mips-linux:
Kód: [Vybrat]
00029adc <is_prime>:
   29adc: 00 04 10 42   srl     $2, $4, 1 <main+0x1>
   29ae0: 24 03 00 02   addiu   $3, $zero, 2 <main+0x2>
   29ae4: 24 06 00 02   addiu   $6, $zero, 2 <main+0x2>
   29ae8: 24 41 00 01   addiu   $1, $2, 1 <main+0x1>
   29aec: 2c 25 00 03   sltiu   $5, $1, 3 <main+0x3>
   29af0: 00 25 18 0a   movz    $3, $1, $5
   29af4: 10 66 00 07   beq     $3, $6, 32 <is_prime+0x38>
   29af8: 00 c0 28 25   move    $5, $6
   29afc: 00 85 00 1b   divu    $zero, $4, $5
   29b00: 24 a6 00 01   addiu   $6, $5, 1 <main+0x1>
   29b04: 00 a0 01 f4   teq     $5, $zero, 7 <main+0x7>
   29b08: 00 00 08 10   mfhi    $1
   29b0c: 14 20 ff f9   bnez    $1, -24 <is_prime+0x18>
   29b10: 00 00 00 00   nop <main>
   29b14: 03 e0 00 08   jr      $ra
   29b18: 00 45 10 2b   sltu    $2, $2, $5

Re:GCC optimalizace pro různé ISA
« Odpověď #6 kdy: 25. 10. 2021, 00:21:34 »
Když to přepíšu do C a nechám zkompilovat zigem (jde to přes libclang a llvm), tak je ta funkce v RV64 podstatně ukecanější, ale neumím určit, jestli to je jiným nastavením optimalizace (ReleaseSmall vs. -Os), nebo se v Zigu se silnějším typovým systémem daří lépe hledat invarianty.

zig cc main.c -target riscv64-linux -Os -o main:
Kód: [Vybrat]
0000000000000000 <is_prime>:
       0: 11 46         addi    a2, zero, 4
       2: 85 45         addi    a1, zero, 1
       4: 63 64 c5 02   bltu    a0, a2, 0x2c <is_prime+0x2c>
       8: 9b 55 15 00   srliw   a1, a0, 1
       c: 09 46         addi    a2, zero, 2
       e: bb 76 c5 02   remuw   a3, a0, a2
      12: 1b 07 06 00   sext.w  a4, a2
      16: b3 37 d0 00   snez    a5, a3
      1a: 33 37 b7 00   sltu    a4, a4, a1
      1e: 7d 8f         and     a4, a4, a5
      20: 05 06         addi    a2, a2, 1
      22: 75 f7         bnez    a4, 0xe <is_prime+0xe>
      24: 13 b5 16 00   seqz    a0, a3
      28: 93 45 15 00   xori    a1, a0, 1
      2c: 2e 85         mv      a0, a1
      2e: 82 80         ret

mhi

  • *****
  • 500
    • Zobrazit profil
Re:GCC optimalizace pro různé ISA
« Odpověď #7 kdy: 25. 10. 2021, 00:50:11 »
KS: Evidentne programujete 'v jinem svete' nez ja :), ty moje rutiny nejsou takhle primocare. Vezmeme tento ARM kod, ktery dela nejakou primitivni operaci s pameti - u toho ale zjistuje pres tabulky jestli ma do pameti pristup (cteni i zapis). Na kodu je videt, ze se tam opakuje vlastne 3x vypocet, ktery gcc neumelo eliminovat, nektere vysledky by sly pouzit opakovane, ale pocitaji se porad znovu. Ten kod je opravdu neoptimalni a hnusny, s tim s bude muset neco udelat. Gcc to dela uplne vsude, x86/x64/arm/aarch64/ppc/riscv/xtensa/... ; JENZE na RISC-V ma tento kod vice nez dvojnasobnou delku na instrukce i delku (nebudu to sem vkladat, je to fakt nuda). Musim vyzkouset jestli primeju gcc pres nejake pomocne promenne ty mezivypocty recyklovat.

Zdrojak sem hodit nemuzu, ma to 3000 radek s hromadou maker a #ifdefu.

Kód: [Vybrat]
   0: 89ba      ldrh r2, [r7, #12]
   2: 88f8      ldrh r0, [r7, #6]
   4: 8afb      ldrh r3, [r7, #22]
   6: 4410      add r0, r2
   8: 6a7a      ldr r2, [r7, #36] ; 0x24
   a: b570      push {r4, r5, r6, lr}
   c: b280      uxth r0, r0
   e: eb00 1003 add.w r0, r0, r3, lsl #4
  12: 011d      lsls r5, r3, #4
  14: f3c0 3404 ubfx r4, r0, #12, #5
  18: 2301      movs r3, #1
  1a: 0c41      lsrs r1, r0, #17
  1c: 40a3      lsls r3, r4
  1e: f852 2021 ldr.w r2, [r2, r1, lsl #2]
  22: 4213      tst r3, r2
  24: d105      bne.n 32 <rtn11+0x32>
  26: f3c0 020b ubfx r2, r0, #0, #12
  2a: f640 73ff movw r3, #4095 ; 0xfff
  2e: 429a      cmp r2, r3
  30: d129      bne.n 86 <rtn11+0x86>
  32: f7ff fffe bl 0 <spec_rdmem_word>
32: R_ARM_THM_CALL spec_rdmem_word
  36: 893b      ldrh r3, [r7, #8]
  38: 7e39      ldrb r1, [r7, #24]
  3a: 88fc      ldrh r4, [r7, #6]
  3c: 4419      add r1, r3
  3e: 89bb      ldrh r3, [r7, #12]
  40: 4408      add r0, r1
  42: 6aba      ldr r2, [r7, #40] ; 0x28
  44: 441c      add r4, r3
  46: 2301      movs r3, #1
  48: b286      uxth r6, r0
  4a: b2c1      uxtb r1, r0
  4c: fa15 f484 uxtah r4, r5, r4
  50: f3c4 3504 ubfx r5, r4, #12, #5
  54: 0c60      lsrs r0, r4, #17
  56: 40ab      lsls r3, r5
  58: f852 2020 ldr.w r2, [r2, r0, lsl #2]
  5c: 4213      tst r3, r2
  5e: d015      beq.n 8c <rtn11+0x8c>
  60: 4620      mov r0, r4
  62: f7ff fffe bl 0 <spec_wrmem>
62: R_ARM_THM_CALL spec_wrmem
  66: 1c60      adds r0, r4, #1
  68: 6aba      ldr r2, [r7, #40] ; 0x28
  6a: f3c0 3504 ubfx r5, r0, #12, #5
  6e: 2301      movs r3, #1
  70: 0c44      lsrs r4, r0, #17
  72: 40ab      lsls r3, r5
  74: 0a31      lsrs r1, r6, #8
  76: f852 2024 ldr.w r2, [r2, r4, lsl #2]
  7a: 4213      tst r3, r2
  7c: d009      beq.n 92 <rtn11+0x92>
  7e: e8bd 4070 ldmia.w sp!, {r4, r5, r6, lr}
  82: f7ff bffe b.w 0 <spec_wrmem>
82: R_ARM_THM_JUMP24 spec_wrmem
  86: 6afb      ldr r3, [r7, #44] ; 0x2c
  88: 5a18      ldrh r0, [r3, r0]
  8a: e7d4      b.n 36 <rtn11+0x36>
  8c: 6afb      ldr r3, [r7, #44] ; 0x2c
  8e: 5519      strb r1, [r3, r4]
  90: e7e9      b.n 66 <rtn11+0x66>
  92: 6afb      ldr r3, [r7, #44] ; 0x2c
  94: 5419      strb r1, [r3, r0]
  96: bd70      pop {r4, r5, r6, pc}

Re:GCC optimalizace pro různé ISA
« Odpověď #8 kdy: 25. 10. 2021, 08:24:15 »
... Na kodu je videt, ze se tam opakuje vlastne 3x vypocet, ktery gcc neumelo eliminovat, nektere vysledky by sly pouzit opakovane, ale pocitaji se porad znovu. Ten kod je opravdu neoptimalni a hnusny, s tim s bude muset neco udelat. Gcc to dela uplne vsude, x86/x64/arm/aarch64/ppc/riscv/xtensa/... ; JENZE na RISC-V ma tento kod vice nez dvojnasobnou delku na instrukce i delku (nebudu to sem vkladat, je to fakt nuda). Musim vyzkouset jestli primeju gcc pres nejake pomocne promenne ty mezivypocty recyklovat.
Jakýkoliv použitelný překladač Cčka ty mezivýpočty nebude recyklovat, protože nesmí! Jsou tam volání na nějaké neznámé spec_* funkce o kterých překladač neví vůbec nic. Takže musí předpokládat, že můžou hrabat úplně na všechno.
Máte tam tři tvrdé resety optimalizátoru a kromě toho ten kód dělá velké kulové. Na tomhle kódu ani neporovnáte optimalizátory ale jen volací konvence různých architektur.

mhi

  • *****
  • 500
    • Zobrazit profil
Re:GCC optimalizace pro různé ISA
« Odpověď #9 kdy: 25. 10. 2021, 09:44:59 »
Volani tech fci jsou fallbacky kdyz neni pristup povolen a neni to cross-page (jsou tam jinak ldr/str), takze bez nich by to zachovat mohl, ale vidite, mozna -Os zauradoval a to mi nedoslo. Zkousel jsem driv jako prvni pokus to napocitat dopredu pri vypoctu ty hodnoty do nejakych promennych bokem, ale to vedlo k uplne stejnemu vysledku, tak nevim kde je chyba. Az vyresim jine problemy, zkusim si s tim jeste pohrat. Prvni kandidat na zlepseni je treba ten zdvojeny write po bytech dole, tim zmizne vic kodu.

Narazil jsem ale i v x86 kodu na dalsi potiz, ktera se bude resit daleko hure nez u toho ARMu:

 3d:   75 09                   jne    48
  3f:   5b                      pop    %ebx
  40:   89 c1                   mov    %eax,%ecx
  42:   5e                      pop    %esi
  43:   e9 fc ff ff ff          jmp    44 
         44: R_386_PC32   xxxx

  48:   5b                      pop    %ebx
  49:   5e                      pop    %esi
  4a:   c3                      ret     

RDa

  • *****
  • 2 487
    • Zobrazit profil
    • E-mail
Re:GCC optimalizace pro různé ISA
« Odpověď #10 kdy: 25. 10. 2021, 09:47:14 »
Jak naznacil JH, - tak mi prijde, ze mezivysledek si prekladac neni schopen odlozit.

Normalni programator by treba pouzil "push/pop", coz ale pak rozbije ESP takze vsechny lokalni promenne skrze [esp+offset] budou spatne.

Nebylo by resenim ty opakujici se vypocty ve zdrojaku vyloucit explicitne do promenny napr.?

RDa

  • *****
  • 2 487
    • Zobrazit profil
    • E-mail
Re:GCC optimalizace pro různé ISA
« Odpověď #11 kdy: 25. 10. 2021, 09:52:30 »
  43:   e9 fc ff ff ff          jmp    44 
         44: R_386_PC32   xxxx


Neni tohle nejaka dynamicka vazba, ktera bude nahrazena z exports/linkerem?

Re:GCC optimalizace pro různé ISA
« Odpověď #12 kdy: 25. 10. 2021, 10:10:00 »
  43:   e9 fc ff ff ff          jmp    44 
         44: R_386_PC32   xxxx

Tohle je tail call. A pokud se pořádně podíváte, tak je i v předchozím ARMovém kódu.

mhi

  • *****
  • 500
    • Zobrazit profil
Re:GCC optimalizace pro různé ISA
« Odpověď #13 kdy: 25. 10. 2021, 10:40:45 »
  43:   e9 fc ff ff ff          jmp    44 
         44: R_386_PC32   xxxx

Tohle je tail call. A pokud se pořádně podíváte, tak je i v předchozím ARMovém kódu.

Ano, ja to vim, ale pro sve ucely (viz zacatek diskuse) ho potrebuju zlikvidovat, aby beh koncil opravdu na nejspodnejsi instrukci. Napadlo mne na konec funkce hodit nejaky asm, ktery by tomu zabranil a pak bych si ho automatizovane odstranoval, ale treba je nejaka lepsi cesta.

Re:GCC optimalizace pro různé ISA
« Odpověď #14 kdy: 25. 10. 2021, 13:11:17 »
  43:   e9 fc ff ff ff          jmp    44 
         44: R_386_PC32   xxxx

Tohle je tail call. A pokud se pořádně podíváte, tak je i v předchozím ARMovém kódu.

Ano, ja to vim, ale pro sve ucely (viz zacatek diskuse) ho potrebuju zlikvidovat, aby beh koncil opravdu na nejspodnejsi instrukci. Napadlo mne na konec funkce hodit nejaky asm, ktery by tomu zabranil a pak bych si ho automatizovane odstranoval, ale treba je nejaka lepsi cesta.
Třeba pro IACA se zajímavý kus kódu značkuje těmahle makry : https://github.com/sifrrich/matrixmult/blob/master/iacaMarks.h

Pokud to má jít do nějakého interního toolu, tak doporučuju pečlivě pročíst dokumentaci k gcc v módu jazykového právníka. On může překladač legálně dělat dost divoké věci. Pokud to musí jít k zákazníkovi, tak stojí za úvahu i commit-push-výpověď ;)