Hlavní navigace

Názor k článku Rychlost CPythonu 3.11 a 3.12 v porovnání s JIT a AOT překladači Pythonu (2) od ZmatenejStrejda - Vyzkoušel jsem si kódy z repozitáře pana autora...

  • Článek je starý, nové názory již nelze přidávat.
  • 23. 11. 2023 22:39

    ZmatenejStrejda

    Vyzkoušel jsem si kódy z repozitáře pana autora a dovolím si rozebrat nebo doplnit některé informace z článku.
    (Určitě se podívejte na odstavec 4)

    Testoval jsem nativní implementaci v C a numba7 primárně na velikosti 4096 a 25500 iteracích.

    Stroje (všechny nastaveny 1 vlákno na jádro)
    1. 1x A8-7650K ~ 1x(4 jádra) @ 4.4GHz
    2. 2x Xeon E5-2620 v3 ~ 2x(6 jader) @ 2.40GHz
    3. 2x AMD EPYC 7452 ~ 2x(32 jader)

    1) Pokud chceme měřit skutečnou rychlost výpočtu, tak dle mého názoru, měřit celkový běh programu nedává moc smysl a mnohem přínosnější je měřit jen čas provedení výpočetní funkce, protože zápis na standardní výstup je celkem pomalý. A to například pomocí gettimeofday() z knihovny sys/time.h a pro python time.time() z knihovny time. Například na stroji 3. trvá nativní výpočet 3.514 sekund a tisk na stdout 2.771 sekund, takže IO prodlužuje dobu běhu programu o cca 78%. Je sice pravda že tam to zdržení je a bude, ale dle mého názoru není zajímavé dokud nebudeme optimalizovat IO.

    2) Ofast, Obad, aneb velmi rychlá střelba do nohy. -Ofast v nativní implementaci nepřináší téměř žádný další výkon oproti -O3. Navíc při dalším rozšiřování programu se dřív nebo později projeví chybným nebo nezvyklým chováním programu.
    Myslím že lepší volbou jsou například -mtune=native a -march=native

    3) Sice Amdahlův zákon nás omezuje, ale naštěstí je tu Gustafsonův zákon. Jednoduše řečeno, Amdahlův říká něco jako že pokud v programu je nějaká sekvenční část, tak více jader nepomůže. Gustafsonův zákon na to jde obráceně a říká něco ve smyslu, že pokud máš příliš mnoho jader, tak zvětši řešený problém a zachováš si tím zrychlení. Tyto zákony se objevují taky pod pojmy slabé a silné škálování.

    4) Výrok: "výpočet ve více vláknech v C lze realizovat mnohem složitěji" Není pravdivý. Již nějakou dobu je tu s námi knihovna OpenMP, která ve světě C/C++ působí jako zázrak, protože pomocí jednoduchého makra
    #pragma omp parallel for paralelizujeme naší smyčku. Pak stačí jen kompilovat kód s flagem -fopenmp a mít v systému balíček openmp. Nejjednodušší použití vypadá například takto

    #pragma omp parallel for
    for (int y = 0; y < height; y++) {

    což vypadá mnohem více zadarmo než

    @jit((int64, int64, int64, UniTuple(UniTuple(int64, 3), 256)), nopython=True, parallel=True)
    def calc_mandelbrot(width, height, maxiter, palette):
    Samozřejmě musíme stejně jako v případě numby vnořit proměnnou cy dovnitř prvního cyklu

    5) Zde je menší porovnání
    C ~ 1 jádro,
    OpenMP ~ všechny jádra,
    Numba ~ všechny jádra

    stroj     | 2048   4096
    __________|_____________________
    1. C      | 61.73  246.7
    1. OpenMP | 16.80  67.21
    1. Numba  | 32.55  130.9
              |
    2. C      | 67.52  269.8
    2. OpenMP | 6.951  27.68
    2. Numba  | 19.28  76.72
              |
    3. C      | 54.24  217.6
    3. OpenMP | 0.883  3.514
    3. Numba  | 2.800  11.10

    Na závěr bych chtěl dodat, že mě velice mile překvapilo kam až to python výkonově dotáhl.