Názory k článku Test: paměti mají čtyřistakrát delší latenci než procesory

  • Článek je starý, nové názory již nelze přidávat.
  • 16. 2. 2009 0:47

    Solitary (neregistrovaný)
    Mobilni CPU - Core Duo T2450 @ 2.00GHz, 2MB L2 Cache, 32bit
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 98.512 98.371
    32bit add 1.005 0.503
    32*32->64bit imul 5.030 2.338
    0*0 imul 5.030
    64/32->32.32 div 39.244
    64bit fadd 2.481 1.159
    64bit NaN+x fadd 180.127 194.701
    64bit fmul 5.000 2.041
    64bit fdiv 37.611 37.009
    32bit load from L1-cache 1.009 pitch=4B
    typical L1-miss load 44.937 pitch=74B
    load from RAM 150.15ns 300.295 pitch=1048572B
    load from RAM 173.76ns 347.514 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 1:29

    djs_core (neregistrovaný)
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 97.517 96.017
    32bit add 1.505 0.515
    32*32->64bit imul 7.115 2.286
    0*0 imul 7.136
    64/32->32.32 div 41.012
    64bit fadd 2.251 1.025
    64bit NaN+x fadd 193.114 214.470
    64bit fmul 5.000 2.026
    64bit fdiv 37.471 36.999
    32bit load from L1-cache 0.993 pitch=4B
    typical L1-miss load 46.144 pitch=74B
    load from RAM 183.59ns 367.184 pitch=1048572B
    load from RAM 161.95ns 323.891 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 2:40

    vlk (neregistrovaný)
    tak pridam tri dost odlisne intely:

    model name : Intel(R) Core(TM)2 CPU U7500 @ 1.06GHz
    cpu MHz : 800.000
    cache size : 2048 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM)2 CPU U7500 @ 1.06GHz
    cpu MHz : 800.000
    cache size : 2048 KB
    cache_alignment : 64
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 86.680 85.348
    32bit add 1.338 0.457
    32*32->64bit imul 4.773 1.528
    0*0 imul 4.795
    64/32->32.32 div 41.996
    64bit fadd 2.251 1.027
    64bit NaN+x fadd 196.149 214.582
    64bit fmul 5.000 2.028
    64bit fdiv 37.471 37.000
    32bit load from L1-cache 0.996 pitch=4B
    typical L1-miss load 31.134 pitch=74B
    load from RAM 275.46ns 220.369 pitch=1048572B
    load from RAM 389.17ns 311.336 pitch=1048572B (1-pass cache flush)


    model name : Intel(R) Xeon(TM) CPU 3.20GHz
    cpu MHz : 3192.202
    cache size : 2048 KB
    cache_alignment : 128
    model name : Intel(R) Xeon(TM) CPU 3.20GHz
    cpu MHz : 3192.202
    cache size : 2048 KB
    cache_alignment : 128
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 100.001 100.000
    32bit add 0.999 0.397
    32*32->64bit imul 11.000 2.044
    0*0 imul 11.000
    64/32->32.32 div 76.057
    64bit fadd 5.260 1.349
    64bit NaN+x fadd 1087.812 1067.265
    64bit fmul 7.998 2.149
    64bit fdiv 45.022 45.079
    32bit load from L1-cache 1.075 pitch=4B
    typical L1-miss load 44.712 pitch=74B
    load from RAM 69.70ns 222.492 pitch=1048572B
    load from RAM 176.68ns 564.008 pitch=1048572B (1-pass cache flush)


    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
    cpu MHz : 2699.132
    cache size : 8192 KB
    cache_alignment : 64
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 21.818 21.816
    32bit add 0.909 0.335
    32*32->64bit imul 4.341 1.828
    0*0 imul 4.342
    64/32->32.32 div 25.023
    64bit fadd 1.945 0.942
    64bit NaN+x fadd 242.969 267.198
    64bit fmul 4.543 0.942
    64bit fdiv 21.804 21.750
    32bit load from L1-cache 0.906 pitch=4B
    typical L1-miss load 25.714 pitch=74B
    load from RAM 61.38ns 165.671 pitch=1048572B
    load from RAM 60.74ns 163.955 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 3:36

    Solitary
    Trosku me zarazi to 8-jadrove i7... to mas nejakou dvouprocesorovou platformu, nebo to se takhle i7 jen prezentuje diky hyperthreadingu?
  • 16. 2. 2009 8:01

    vlk (neregistrovaný)
    jo, je to jeden procesor a je to 4-jadro a kazde znich ma dva virtualne jadra (HT)
    + v procesore je trojkanalovy radic DDR3
  • 16. 2. 2009 9:05

    vencas (neregistrovaný)
    Když vypneš v BIOSu HT, tak by to mělo běžet víceméně 2x rychleji, ne? Docela by mě to zajímalo, uvažuju o koupení i7 _nebo_ Phenomu na komilování a chroustání čísel. Budu vděčný.
  • 16. 2. 2009 2:46

    tester (neregistrovaný)
    Mam taky pocit, ze RDTSC v pripade novych Intel CPU vobec nereflektuje tiky CPU. Preto sa zda, ze ta instrukcia trva 100T. Vid http://en.wikipedia.org/wiki/Time_Stamp_Counter
  • 17. 2. 2009 22:27

    bez přezdívky
    No jo clovek se ma porad co ucit. Je videt ze inzenyri Intelu opet nezklamali a dodrzeli se sve tradice "kdyz je mozne udelat neco dvema zpusoby zvolme si ten horsi". Kdyz uz te instrukci zmenili semantiku tak meli taky vymyslet novy opcode a dat tam citace 2: cycle counter a wall clock counter.
  • 16. 2. 2009 3:45

    Mips (neregistrovaný)
    Po přeložení defaultním g++ z Ubuntu 8.04 64-bit [g++ (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3)]
    
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      66.772       64.011
          32bit         add         1.004        0.341
          32*32->64bit  imul        4.795        1.520
                   0*0  imul        4.796
          64/32->32.32  div        41.016
          64bit         fadd        2.252        1.030
          64bit  NaN+x  fadd      193.185      214.474
          64bit         fmul        5.000        2.030
          64bit         fdiv       37.471       37.005
        32bit load from L1-cache    1.073    pitch=4B
    Segmentation fault
    Tedy prakticky totožné s tím Xeonem v článku (až do segfaultu).
  • 16. 2. 2009 6:52

    Tom (neregistrovaný)
    model name      : Intel(R) Core(TM)2 Duo CPU     T7500  @ 2.20GHz
    cpu MHz         : 2201.000
    cache size      : 4096 KB
    model name      : Intel(R) Core(TM)2 Duo CPU     T7500  @ 2.20GHz
    cpu MHz         : 2201.000
    cache size      : 4096 KB
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      59.592       58.676
          32bit         add         0.920        0.314
          32*32->64bit  imul        4.375        1.401
                   0*0  imul        4.397
          64/32->32.32  div        37.916
          64bit         fadd        2.064        0.943
          64bit  NaN+x  fadd      178.103      196.701
          64bit         fmul        4.583        1.860
          64bit         fdiv       34.349       33.919
        32bit load from L1-cache    0.917    pitch=4B
        typical L1-miss load       56.843    pitch=74B
        load from RAM  151.16ns   332.709    pitch=1048572B
        load from RAM   12.64ns    27.825    pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 7:06

    xxx (neregistrovaný)
    a jak se lisi ruzne kompilery co se tyka vyuziti ruznych registru, aby se instrukce
    staly nezavislymi a dalsi chytre zmeny v kodu ktere provede kompiler ???
  • 16. 2. 2009 7:42

    Zdenek (neregistrovaný)
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
    model name	: Intel(R) Xeon(R) CPU           L5430  @ 2.66GHz
    cpu MHz		: 2666.673
    cache size	: 6144 KB
    cache_alignment	: 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      42.681       42.681
          32bit         add         1.338        0.454
          32*32->64bit  imul        6.346        2.027
                   0*0  imul        6.373
          64/32->32.32  div        23.595
          64bit         fadd        2.251        1.035
          64bit  NaN+x  fadd      194.284      214.585
          64bit         fmul        5.000        2.028
          64bit         fdiv       22.471       22.001
        32bit load from L1-cache    0.995    pitch=4B
        typical L1-miss load       62.231    pitch=74B
        load from RAM  150.62ns   401.661    pitch=1048572B
        load from RAM   11.02ns    29.378    pitch=1048572B (1-pass cache flush)
    
    
  • 16. 2. 2009 7:58

    Jirka (neregistrovaný)
    Neni tenhle test vuci tem procesorum s cachi <=1MB trochu nefer? To, ze Intel(R) Xeon(R) CPU 5160 @ 3.00GHz se 4 MB cache "se nenecha zmast" nemusi preci znamenat, ze je chytrejsi, ale pouze to, ze ma dalsi 3 MB cache k dispozici.

    Nebo se mylim? Jak test dopadne pri 4 MB dat? Bude to jen zhruba ctyrnasobek, nebo to take uplne ulitne?
  • 17. 2. 2009 14:20

    bez přezdívky
    Sice jsem ted linej to zkusit, ale myslim ze to dopadne stejne jako s 1MB. Test 1pass cache flush vypada takto:

    (1) Nejdriv se alokuje 150MB pole, to se vynuluje a pak precte

    (2) Pak teprv se dela vlastni test na datech (v jinem poli) s PITCH (na jehoz velikosti uz by to nemelo moc zalezet, pokud se predtim povedlo vyprazdnit cache).

    Kdyby cache byla uplne hloupa a pri prvnim pristupu k nejakemu cislu si ho vzdy zapamatovala (to znamena ze musi jine vyhodit) tak bych ji tim 150MB polem vyprazdnil. Jenze u Intelu k tomu nedojde a musi se s tim cvicit daleko vic aby cache pochopila ze ma na predchozi data zapomenout.

    PS: to 150MB pole se pochopitelne zapisuje a cte s incrementem 4 byty.
  • 17. 2. 2009 21:28

    bez přezdívky
    Tak jsem premohl lenost. Zaver si udelejte sam. Mozna vam k tomu pomuze kdyz si povsimnete, ze i kdyz vyprazdnuju cache pomoci 2GB pole tak dostavam pri dukladnem vyprazdneni stejne casy. Pro 1pass flush se postupne prodluzuji, ale stale jsou lepsi nez ma dukladny flush. Pritom oboji pracuji na stejne velikem poli. Jediny rozdil je ze dukladne vyprazdneni pote co provede 1pass flush pokracuje tim ze intenzivne pouziva ruzne mensi casti toho pole.
    
    
    POCITAC FIREBALL1 (4jadro)
    model name      : Intel(R) Xeon(R) CPU            5160  @ 3.00GHz
    cpu MHz         : 2992.494
    cache size      : 4096 KB
    cache_alignment : 64
    
    mazaci blok velikosti 150MB:
    
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
        32bit load from L1-cache    1.001    pitch=4B 
        typical L1-miss load       64.689    pitch=74B
        load from RAM  142.65ns   426.877    pitch=1048572B
        load from RAM    9.65ns    28.889    pitch=1048572B (1-pass cache flush)
    
    mazaci blok velikosti 1GB:
    
        32bit load from L1-cache    1.001    pitch=4B 
        typical L1-miss load       64.366    pitch=74B
        load from RAM  142.02ns   424.983    pitch=1048572B
        load from RAM   58.34ns   174.595    pitch=1048572B (1-pass cache flush)
    
    mazaci blok velikosti 2GB:
    
        32bit load from L1-cache    1.001    pitch=4B 
        typical L1-miss load       64.672    pitch=74B
        load from RAM  142.19ns   425.489    pitch=1048572B
        load from RAM   98.33ns   294.239    pitch=1048572B (1-pass cache flush)
    
    
  • 16. 2. 2009 8:25

    Petr Tesařík

    Tenhle nápad s testováním CPU není až tak špatný, ale neodpustím si několik poznámek:

    1. Nepochopil jsem tu sekci Měření v Linuxu. Správný postup je přece zajistit, že adresovaná paměť bude vždy residentní, viz mlock(2), a potom zakázat přerušení po celou dobu trvání testu.
    2. Pokud vdím, autor při testování latence RAM pozapomněl na stránkování, resp. na velmi omezenou velikost TLB cache. Nejlepší by bylo stránkovací jednotku úplně vypnout, ale to je docela problém, pokud má test běžet v nějakém OS. Jako druhé nejlepší řešení se mi tak pro PITCH=1MiB zdá projít celou oblast jednou (a tím naplnit TLB cache), pak přičíst nějaký malý offset, tak aby adresa zůstala ve stejné stránce, tj. třeba 2KiB), ale aby CPU nemohl znovu využít již naplněnou L2 cache (takže např. 2KiB), a provést vlastní test.

    Jinak též všem zainteresovaným vřele doporučuji přečíst si tuhle analýzu od Ulricha Dreppera:
    What Every Programmer Should Know About Memory

  • 17. 2. 2009 16:06

    bez přezdívky
    Mate uplnou pravdu. Kdyz to budu chtit zmerit vedecky, tj. izolovat od sebe
    jednotlive priciny latence, tak bych to mel delat pokud mozno bez OS, se
    zakazanym prerusenim, s vypnutym strankovanim a v konfiguracnich bitech
    procesoru bych jeste mohl zakazat cache, nebo aspon vynutit cache flush kdyz
    to potrebuju (matne si vzpominam ze nejmin jedno z toho je mozne na intelech
    docilit nejakou privilegovanou instrukci).

    Jenze lenost mi zabranila v implmentaci neceho tak velkolepeho. Proto jsem
    se rozhodl pro mene vedecky (statisticky) pristup, kdy vsechny hierarchie
    cache vcetne TLB beru jako jednu cernou skrinku. Slo mi o to, vedet kolik
    radove ztratim za cache miss a kolik maximalne (pokud se k nemu neprida
    jeste swap nebo taskswitch nebo jina pohroma). Tim jsem prestal na TLB
    myslet a ani v clanku jsem ji nezminil (coz je urcite chyba).

    Myslim ale, ze pro praxi je asi lepsi takovyto souhrnny test i kdyz je
    vlastne na pul cesty mezi aplikacnimi testy a pomerne jednoznacnym merenim
    aritmetickych instrukci. Napriklad,kdybych to delal "velkolepe" bez OS a mel
    vypnutou cache tak bych nejspis neprisel na to ze Intel Xeon ma lepsi
    chovani cache po jednorazovem preplaveni daty.

    Nicmene s tou TLB jste me privedl na myslenku, ze vlastne netestuju dobu
    pristupu k pameti ale nejmene dobu 2 pristupu, protoze nejspis temer vzdy
    vypadnu z TLB. A vlastne jsou to mozna 3 pristupy, protoze ty 2 instrukce
    MOV se asi provadeji zaroven na vsech pocitacich (a pouze intel pak nestihne
    udelat jeste tu inktementaci pointeru). Vysvetluju si to tak ze ve stare
    verzi, kdy se provadely instrukce seriove, se pri TLB-miss nacetla (alespon)
    do cache nejspis i TLB-entry potrebna pro nasledujici instrukci.

    V nove verzi kdy bezi 2 MOVy zaroven a vytvori tak 2 vyjimky (nejakeho
    vnitrniho typu -- intel doplnuje TLB na rozdil od PowerPC automaticky a
    negeneruje opravdovou vyjimku pro OS) se asi nacitani serializuje a mozna ze
    se nekontroluje ze tataz data uz mame... Bohuzel tohle vysvetleni prilis
    neobjasnuje namerene casy, a navic by se musel cist naraz asi 1KB
    TLB-polozek abychom tim pokryli pitch=1MB. Takze to asi taky nebude dobre.

    Rozhodne ale duvod nebude v prereadu jak pisu v clanku, protoze se ten efekt
    projevuje i na starych CPU (K6) o kterych pochybuju ze neco takoveho mely.
    Musi to byt neco spolecneho pro vsechny ia32 procesory a TLB se jako takove
    vysvetleni uplne nabizi.

    Jeste by se nabizelo jako vysvetleni prokladani pristupu do pameti. Kdyz se
    jde do jine banky DRAM tak je mozne v dobe kdy cekame na vybavani zadat v
    urcitem casovem okne command pro jinou banku. Tuhle vlastnost myslim mely
    SDRAMky i v dobach K6. Takze v OLDVERSION by to vypadalo tak ze zada
    pozadavek na precteni TLB a temer zaroven s nim i pozadavak na data (z
    predchozi adresy pro kterou TLB uz mame z minula prectenou). V nove verzi
    ale instrukce zadaji o doplneni TLB zaroven a protoze TLB-entries bydli ve
    stejne bance DRAM, prokladani nebude mozne. Totez pak plati o datech,
    protoze kdyz jsou jen 1MB od sebe tak budou vetsinu casu ve stejne bance. To
    by uz vysvetlovalo proc je to na vetsine pocitacu priblizne 2* delsi. Ale
    asi je to taky blbost.


    V kazdem pripade dik za inspirujici komentar.
  • 16. 2. 2009 9:07

    vencas (neregistrovaný)
    Nemáte někdo přístup k počítači, kde je gcc i icc? Moc by mě zajímalo srovnání, jestli to intel optimalizuje na svoje procesory lépe. Tvrdí se, že na čísla bývá o pár procent nebo desítek procent rychlejší.
  • 16. 2. 2009 9:39

    tester (neregistrovaný)
    V pripade rucne napisaneho kodu v ASM tam ten kompiler ziadne zazraky nespravi. Zvlast v pripade, kedy je kod umyseslne naprogramovany "zle", aby sa napriklad otestoval throughput.
  • 16. 2. 2009 9:19

    secondary.adjunct (neregistrovaný)
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 116.002 114.022
    32bit add 1.999 0.672
    32*32->64bit imul 3.000 1.044
    0*0 imul 3.000
    64/32->32.32 div 48.778
    64bit fadd 2.980 0.991
    64bit NaN+x fadd 4.038 0.992
    64bit fmul 3.998 0.991
    64bit fdiv 22.472 20.991
    32bit load from L1-cache 0.546 pitch=4B
    typical L1-miss load 24.420 pitch=74B
    load from RAM 222.76ns 245.037 pitch=1048572B
    load from RAM 240.32ns 264.352 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 9:57

    anonymní
    Zaujalo mě to s Quakem a číslováním Athlonů, nemohl by se o tom, prosím, autor trochu rozepsat? Protože by mě celkem zajímalo, jak to hodnotili. Pokud šlo o Quaka 3, tak tam má hlavní vliv na rychlost, pokud se nemýlím, grafická karta. Děkuji.
  • 16. 2. 2009 10:54

    anonymní
    Ako bolo uz spomenute intel procesory nemaju uplne viazane Rdtsc na pocet vykonanych instrukcii.Zalezi od modelu. (http://download.intel.com/design/processor/manuals/248966.pdf)
    Processor families increment the time-stamp counter differently:
    • For Pentium M processors (family [06H], models [09H, 0DH]); for Pentium 4
    processors, Intel Xeon processors (family [0FH], models [00H, 01H, or 02H]);
    and for P6 family processors: the time-stamp counter increments with every
    internal processor clock cycle.
    The internal processor clock cycle is determined by the current core-clock to bus-
    clock ratio. Intel® SpeedStep® technology transitions may also impact the
    processor clock.
    • For Pentium 4 processors, Intel Xeon processors (family [0FH], models [03H and
    higher]); for Intel Core Solo and Intel Core Duo processors (family [06H], model
    [0EH]); for the Intel Xeon processor 5100 series and Intel Core 2 Duo processors
    (family [06H], model [0FH]); for Intel Core 2 and Intel Xeon processors (family
    [06H], display_model [17H]); for Intel Atom processors (family [06H],
    display_model [1CH]): the time-stamp counter increments at a constant rate.
    That rate may be set by the maximum core-clock to bus-clock ratio of the
    processor or may be set by the maximum resolved frequency at which the
    processor is booted. The maximum resolved frequency may differ from the
    maximum qualified frequency of the processor, see Section 18.20.5 for more
    detail.
    The specific processor configuration determines the behavior. Constant TSC
    behavior ensures that the duration of each clock tick is uniform and supports the
    use of the TSC as a wall clock timer even if the processor core changes frequency.
    This is the architectural behavior moving forward.Vol. 3 18-43

    To determine average processor clock frequency, Intel recommends
    the use of EMON logic to count processor core clocks over the period
    of time for which the average is required. See Section 18.20,
    “Counting Clocks,” and Appendix A, “Performance-Monitoring Events,” for more information

    Pravdepodobne tie vysledky z Intelov budu asi blbe.
  • 16. 2. 2009 11:26

    BLEK. (neregistrovaný)
    To opakované měření přístupu k paměti pomocí pitch mi přijde dost divné --- je to dost ovlivněno asociativitou cache.

    Pokud máme v testu 512MiB ram a čteme z toho s pitch 1MiB-4, tak tak načteme 513 řádek. To celkem dává (při velikosti řádky 64) 32832 bytů. To by se normálně do cache vlézt mělo. Jenomže se to tam nevleze proto, že cache není ideálně asociativní paměť, ale je adresovaná.

    Z fyzické adresy se vezme několik bitů (5 nebo 6) jako offset v řádce. Další bity (až do log2(velikost cache)/asociativita) určují adresu v cachi --- podle této adresy se cache adresuje podobně, jako nomální paměť. Na každé adrese se nachází tolik řádek, jaká je asociativita cache (je tam plná adresa řádky a její obsah) --- všechny tyhle řádky se porovnají s požadovanou adresou a pokud některý z nich sedí, tak se data v cachi nalezla.

    Takže pokud např. AMD má L1 cache 2-cestně asociativní o velikosti 64KiB s řádkou 64 bytů, znamená to, že se bity 0-5 berou jako offset v řádce, bity 6-14 jako adresa v cache a na každé adrese jsou dva řádky. Důsledek je ten, že pokud budeme opakovaně číst pouze 3 hodnoty na adresách 0, 32768 a 65536, tak se nám do L1 cache nevejdou! (všechny tři se totiž namapujou na stejnou adresu, na níž jdou uložit však pouze dvě řádky)

    U zmíněného testu, kde se 512MiB prochází s krokem 1MiB-4 pak výsledek na asociativitě a algoritmu na vyměňování jednotlivých řádek na dané adrese může záviset --- na každou adresu v cachi přečteme 16 (64/4) hodnot --- tedy na 16-cestně asociativní cachi by měl test projít zcela z cache, na méněcestně asociativní se bude část číst z paměti a část z cache.

    Navíc je to ještě zamícháno tím, že cache se indexuje fyzickými adresami a program pracuje s virtuálními --- ihned po bootu program dostane jakž takž souvislý úsek paměti, po nějaké době běhu však stránky budou náhodně rozházeny. Ihned po bootu nám tedy více paměťových míst s pitchem 1MiB bude ležet na konfliktních adresách v cachi, po nějaké době běhu systému se však bity "12 a výše" v adrese stanou náhodné a bude docházet k méně konfliktům v cachi.

    Test měřící hrubou dobu přístupu do paměti by měl být udělán tak, aby se data opravdu četla z paměti, tedy přečíst několikrát víc fyzických dat než je velikost cache, tak že to jakákoli organizace cache to není schopna zachytit. Test v programu bych upravil tak, že po dojetí na horních 512MB začne číst zase od začátku, ale o několik cacheline posunutý a takhle pořád dokola, dokud nepřečte několikrát více dat než je velikost cache.

    Procesory Intel taky mají prefetch, jsou schopny se naučit na průchod pamětí s konstantním krokem a dělat podle toho prefetch. Pokud nechceme efekt tohoto prefetche měřit, tak by se i samotná hodnota pitch měla měnit během běhu.
  • 18. 2. 2009 12:29

    bez přezdívky

    Asi jsem blbej, ale nejak vas prispevek uplne nechapu. Myslel jsem ze kdyz to udelam tak, ze nejprve nejak vyprazdnim cache a pak budu cist s takovou pitch aby mi preread nemohl moc pomahat (tim ze by dostal data do L2 cache driv nez si o ne program rekne) tak dostanu (kdyz se zanedba TLB-miss) zhruba dobu latence pameti krat pocet prectenych cisel. A to by nemelo na cachich zaviset vubec, protoze stejnou adresu (ani z jejiho okoli) uz podruhy nectu. Kdyz to pak 20* opakuju tak to opakuju i s tim vyprazdnovanim (proto to tak dlouho trva). Jeste takova technicka drobnost: data z toho 512MB pole se musi na zacatku aspon na kazdem 4tem KB precist/zapsat aby se prislusna stranka v linuxu vubec namapovala a nezdrzovalo to az pri testovani. Pri kazdem opakovani se zminena pole alokuji a znovu uvolnuji.

    Takze problem je hlavne v tom, jak delat vyprazdnovani cache, abych z ni data temer urcite dostal pryc. Zjistil jsem, ze jen zapsat 150MB (s pitch=4) a zase je precist na nekterych CPU nestaci.

    Kdyby bylo vypnute strankovani tak zapsanim a opetovnym prectenim 150MB (s pitch=4) je cache vyprazdnena urcite. Se zapnutym strankovanim je to slozitejsi, protoze mi alokace pameti muze vratit stranky jejihz fyzicke adresy se mapuji na stejne misto v cache. V extremnim pripade by se mohlo stat, ze diky takovemuto sdileni zustane jine misto cache zcela netknute a jako na potvoru v nem preziji data co pak budu cist (kterych jak jste spravne podotkl je pomerne malo).

    Obecne je toto problem i operacniho systemu, protoze kdyz se to stane, tak se tim zhorsi vyuziti cache. Proto se tomu nektere UNIXy se snazi zabranit tzv. barvenim stranek, kdy se snazi alokovat stranky ktere v cache pak nekoliduji. Jenze pokud si vzpominam, tak ma Linux pouze barveni objektu uvnitr slabu. Takze se po nejake dobe da ocekavat, ze fyzicke stranky budou pridelovany vicemene nahodne. Rekneme ze je to nas pripad a zeptejme se jaka je pravdepodobnost, ze se celou cache nepodari vyprazdnit, tj. ze existuje aspon 1 adresa stanky uvnitr cache ktera nebude zasazena.

    Nejdriv obarvim stranky pameti tak ze 2 dostanou stejnou barvu pokud se mapuji na stejnou adresu v cache. Barev je C=velikost_cache/velikost_stranky coz v pripade 4KB stranky a 4MB L2-cache je C=1024. Pak me zajima horni odhad na pravdepodobnost ze ani po K=150MB/4KB=150*256 nahodnych vyberech (bez vraceni) stranky nezasahnu barvu 1.

    Pri prvnim vyberu je to zjevne (1-1/C). V dalsim vyberu je o neco mene nez (1-1/C) protoze uz jsem jednu non-1 barvu pouzil. Me ale jde jen o horni odhad takze budu brat (1-1/C). Z toho mam pravdepodobnost (1-1/C)^K ze minu barvu 1 (ostatni barvy muzu nebo nemusim minout).

    Nakonec mi jde o to jaka je pravdepodobnost ze minu NEJAKOU barvu. To se da zhora odhadnout jako C*(1-1/C)^K. Neformalne receno je to diky tomu ze bud minu barvu 1, nebo 2, nebo... C. Horni odhad je to proto, ze nejde o disjunktni jevy (vzorec (1-1/C)^K pouzity pro barvu 1 v sobe ma i prispevek jevu ze minu barvu 1 i 2 a neminu ostatni, stejne tak jako vzorec (1-1/C)^K pouzity pro barvu 2 --- tim tam napr. tyto jevy zapocitam vickrat).

    Po dosazeni

    
    gnuplot> C=1024.0
    gnuplot> print C*(1-1.0/C)**(150*1024/4)
    5.20354763762773e-14
    

    Takze pravdepodobnost, ze se nepodari vyprazdnit cache je temer zanedbatelna.

    Pekne je videt v praxi, ze moc nezalezi na velikosti toho vyprazdovaciho pole. At je to 150MB nebo 2GB tak jsou vysledky pri dukladnem vyprazdnovani stejne. Vysledky pri 1pass-flush se lisi, ale to myslim je nejaky dalsi efekt.

    
    
    model name      : Intel(R) Xeon(R) CPU            5160  @ 3.00GHz
    cpu MHz         : 2992.494
    cache size      : 4096 KB
    cache_alignment : 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
    pro mazaci blok velikosti 150MB:
        32bit load from L1-cache    1.001    pitch=4B
        typical L1-miss load       64.689    pitch=74B
        load from RAM  142.65ns   426.877    pitch=1048572B
        load from RAM    9.65ns    28.889    pitch=1048572B (1-pass cache flush)
    
    pro mazaci blok velikosti 1GB:
        32bit load from L1-cache    1.001    pitch=4B
        typical L1-miss load       64.366    pitch=74B
        load from RAM  142.02ns   424.983    pitch=1048572B
        load from RAM   58.34ns   174.595    pitch=1048572B (1-pass cache flush)
    
    pro mazaci blok velikosti 2GB:
        32bit load from L1-cache    1.001    pitch=4B
        typical L1-miss load       64.672    pitch=74B
        load from RAM  142.19ns   425.489    pitch=1048572B
        load from RAM   98.33ns   294.239    pitch=1048572B (1-pass cache flush)
    
    
  • 19. 2. 2009 1:17

    BLEK. (neregistrovaný)
    Pokud jsou na těch řádkách v L2 cache nějaká počítadla přístupu, tak tenhle kus kódu ta počítadla napumpuje na maximum (protože do L1 se to nevejde kvůli asociativitě):

    for(int rep=0; rep<32; rep++)
    for(int i=0; i<mem_size; i+=pitch) acc+=*(u32*)(&adr[i]);

    --- takže se pak stane, že ani lineární přístup to nevyprázdní, pokud cache vyhazuje stránky s nejmenším počítadlem přístupu.

    "Kdyby bylo vypnute strankovani tak zapsanim a opetovnym prectenim 150MB (s pitch=4) je cache vyprazdnena urcite."

    --- nemusí, protože z těch řádek na jedné adrese si procesor vybere jednu, kterou vyprázdní. Může si pořád vybírat tu stejnou (s nejmenším počítadlem přístupu), takže pak vyprázdní pouze (velikost cache/asociativita) bytů v cache.

    "Barev je C=velikost_cache/velikost_stranky"

    Nikoli. Barev je velikost cache/asociativita_cache/velikost_stranky.

    "Pak me zajima horni odhad na pravdepodobnost ze ani po K=150MB/4KB=150*256 nahodnych vyberech (bez vraceni) stranky nezasahnu barvu 1."

    Jednou ji zasáhnout nestačí. Je třeba dotyčnou barvu zasáhnout tolikrát, kolik je asociativita cache. A ani to stačit nemusí, procesor může při všech těchto zásazích vyhodit tu samou řádku a ostatních (asociativita-1) řádek tam nechat (což se asi opravdu děje vzhledem k tomu, že lineárním přístupem se tu cache nepodařilo vyprázdnit).

    Ja vyprázdnit cache? instrukce wbinvd (ale ta jde volat jen z kernel módu) nebo clflush (ta jde i uživatelským procesem, ale je až od SSE2).
  • 19. 2. 2009 10:20

    klusacek (neregistrovaný)

    "Nikoli. Barev je velikost cache/asociativita_cache/velikost_stranky"

    To ano, ale intuitivne ocekavam ze ta pravdepodobnost moc nezmeni. I kdyby to bylo 1000* horsi tak to porad bude zanedbatelne.

    "--- takže se pak stane, že ani lineární přístup to nevyprázdní, pokud cache vyhazuje stránky s nejmenším počítadlem přístupu."

    ano je spravna pripominka. Takze jsem to prelozil bez toho for(rep...) a vysledek pro pocitac fireball je zde. Temer nelisi od puvodni verze. chce vymyslet duvod proc 1-pass flush nevyprazdni local-multi-pass ano (a jeste jenom na intelech)

    
    
    model name      : Intel(R) Xeon(R) CPU            5160  @ 3.00GHz
    cpu MHz         : 2992.494
    cache size      : 4096 KB
    cache_alignment : 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      65.011       64.011
          32bit         add         1.003        0.343
          32*32->64bit  imul        4.771        1.528
                   0*0  imul        4.769
          64/32->32.32  div        41.051
          64bit         fadd        2.252        1.031
          64bit  NaN+x  fadd      195.300      214.651
          64bit         fmul        5.000        2.031
          64bit         fdiv       37.471       37.002
        32bit load from L1-cache    1.001    pitch=4B
        typical L1-miss load       64.667    pitch=74B
        load from RAM  140.63ns   420.839    pitch=1048572B
        load from RAM   10.07ns    30.127    pitch=1048572B (1-pass cache flush)
    
    

    Kdyby se to ridilo jen pomoci LRU citacu, tak by pak 3* opakovany one-pass flush mel zvitezit nad 1* opakovanym zapisem a ctenim dat. Jenze se to nestane:

    
    model name      : Intel(R) Xeon(R) CPU            5160  @ 3.00GHz
    cpu MHz         : 2992.494
    cache size      : 4096 KB
    cache_alignment : 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      65.011       64.011
          32bit         add         1.003        0.343
          32*32->64bit  imul        4.768        1.528
                   0*0  imul        4.769
          64/32->32.32  div        41.056
          64bit         fadd        2.252        1.031
          64bit  NaN+x  fadd      195.300      214.584
          64bit         fmul        5.000        2.031
          64bit         fdiv       37.471       37.002
        32bit load from L1-cache    1.001    pitch=4B
        typical L1-miss load       64.604    pitch=74B
        load from RAM  141.97ns   424.833    pitch=1048572B
        load from RAM   11.21ns    33.558    pitch=1048572B
    
    

    Dokonce i kdyz jsem opakovani udelal uvnitr smycky, tj. ze jsem cetl 10* po sobe totez misto z pameti (ovsem nevim jestli se to bude zapocitavat do counteru L2 cache kdyz to jde tak rychle po sobe), tak se vysledek posledni radky testu moc nezmenil --- vychazelo 14.22 ns.

    Takze bud se ty countery v L2 cache updatuji nejak pomaleji, nebo je tam jeste jiny mechanismus. V te posledni verzi mohla mit data co chci vyprazdnit counter maximalne 2, oproti datum kterymi to vyprazdnuju, ktere ho mely maximalne 10. Musi tam byt jeste jiny mechanismus (treba nejaky pomaly update counteru, nebo kdovico jinyho) ktery by to vysvetlil.

  • 19. 2. 2009 18:26

    anonymní
    Mozne vysvetleni Intelovskeho chovani by mohlo byt v interakci L1 a L2 cache.

    Kdyby se citace v L2 incrementovaly pouze kdyz se data z L2 stehuji do L1, tak pokud data pouzivam vickrat avsak pouze lokalne, zvysilo by to L2 citace jen o 1, a zbytek by sel na L1 citace. Pri globalnim opakovani bych sice teoreticky mohl zvysovat citace L2, ale nez to pole cele projdu tak dojde k periodickemu vynulovani citacu (lepe receno vydeleni 2ma).

    Takze ani ciste lokalni ani ciste globalni pristup ke cache flush nezafunguje, protoze citace L2 stranek budou neco jako 1 nebo 2 a bude se proto prepisovat stale ta stejna stranka.

    Naopak kombinovany pristup, ktery pouziva mensi bloky, ktere se vejdou do L2 ale nevejdou do L1, nuti k castemu pohybu mezi L1 a L2, coz vede ke zvysovani citacu v L2 a naslednemu vyhazovani ostatnich stranek.

    Ted je jen otazka v cem se AMD lisi, ze se v tomto ohledu chova hur. Jak jsem se dival na vysledky tak i Phenomy se chovaji podobne jako Opterony.
  • 21. 2. 2009 10:39

    BLEK. (neregistrovaný)
    Teď jsem ten program zkoumal důkladněji a přišel jsem ještě na jednen zásadní problém:

    pokus o vyprazdňování cache pomocí calloc() a čtení této paměti.

    calloc() totiž pro větší velikost zavolá pouze mmap() a nenuluje tu paměť (ze specifikace mmap musí být vrácená paměť již vynulovaná). Při pokusu o čtení stránky, na kterou se nikdy nezapisovalo, Linux vrátí připravenou nulovou stránku a namapuje ji read-only; až když se na stránku zapíše, tak ji Linux fyzicky alokuje. Takže celý cyklus
    for(int i=0; i<L; i++) acc+=dummy[i];
    čte vlastně pouze z jedné nulové stránky. Takže to cache nevyprázdní skoro vůbec.

    Když jsem ten cyklus nahradil:
    for(int i=0; i<L; i++) dummy[i] = 1;
    --- tak sice rozdíly mezi one-pass a multi-pass flush byly (asi vlivem jevů popsaných výše), ale už ne 10-násobné:
    model name : Intel(R) Xeon(R) CPU 5110 @ 1.60GHz
    cpu MHz : 1595.929
    cache size : 4096 KB
    cache_alignment : 64
    load from RAM 232.22ns 370.602 pitch=1048572B
    load from RAM 195.94ns 312.702 pitch=1048572B (1-pass cache flush)

    [ předtím to bylo:
    load from RAM 222.61ns 355.277 pitch=1048572B
    load from RAM 16.06ns 25.627 pitch=1048572B (1-pass cache flush)
    ]
  • 21. 2. 2009 17:43

    klusacek (neregistrovaný)
    To je ono! Vynikajici detektivni prace ;-) Uprimne gratuluju (a zaroven mlatim hlavou o stul ze jsem zapomel jak presne jsem kdysi implementoval vlastni funkci c_alloc()).

    Jenom jeste nerozumim, proc pro AMDcka vychazely oba casy skoro stejne. Ze by mmap() fungoval jinak u Intelu a AMD?
  • 16. 2. 2009 11:47

    BLEK. (neregistrovaný)
    "Je pozoruhodné, že RDTSC trvá u některých Intelů až sto taktů. Přitom nevidím důvod, proč by musela být delší než jeden takt, když je to vlastně jen přečtení registru TSC čítače do %edx:%eax."

    Důvod je ten, že ten registr TSC není připojen přímo do výkonných jednotek procesoru, takže za jeden tik do registrů ta data v žádném případě dostat nejdou. Připojit by tam sice šel, ale bylo by to zbytečné plýtvání plochou kvůli optimalizaci instrukce, která se vyskytuje v programech strašně málo.

    Takže se takovéhle málo-se-vyskytující instrukce do procesoru hardwarově neimplementují, ale řeší se mikrokódem ... a ten pak až třeba těch 100 tiků trvá (na Pentiu 4 je mikrokód zvlášť pomalý).

    Mikrokód je i důvod toho, proč NaN trvá tak pomalu --- holt se návrhářům Pentia 4 chtělo ušetřit pár hradel v koprocesoru, tak to udělali tak, že v případě nějakého málo častého stavu (generování NaN) spustí v procesoru mikrokód, který to dopočítá.

    "Vypadá to, jako by ji Linux chytil a do správného FPU registru strčil NaN jako výsledek a zase se vrátil, čímž by emuloval IEEE aritmetiku."

    Takhle funguje IA-64. Jeho koprocesor opravdu kvůli jednoduchosti neumí počítat s NaNy, nekonečny a nenormalizovanými čísly (to jsou čísla tak malá, že exponent obsahuje nejmenší záporné číslo a mantisa začíná nulovým bitem) a při jejich výskytu vyhodí vyjímku, kterou zpracuje operační systém a výsledek dopočítá.

    Na X86 tyto typy vyjímek nejsou (Linux nic dopočítávat nemusí), nicméně v Intelu to udělali zjevně tak, že výsledek dopočítají pomocí mikrokódového programu uvnitř procesoru.

    "Je to poměrně zrádné chování, představte si real-time program, který má zpracovávat nějaká data, ve kterých se občas objeví blok Infu nebo NaNu - rázem to běží tisíckrát pomaleji!"

    Real-time programy hlavně nemají běžet na X86 a na Linuxu. Ale na počítačích k tomu určených (nejlépe bez cache) a operačních systémech k tomu určených (Vxworks, Qnx apod.).

    X86 i Linux je prostě optimalizováno na minimalizaci průměrné doby výpočtu, nikoli na minimalizaci nejhorší doby výpočtu. Pokud tedy návrhář procesoru může zrychlit běžné násobení třeba o jeden takt za cenu, že zpomalí málo běžné násobení (NaN) o 1000 taktů, tak to klidně udělá, protože optimalizuje průměrnou dobu výpočtu.
  • 16. 2. 2009 12:41

    vtech (neregistrovaný)
    "Real-time programy hlavně nemají běžet na X86 a na Linuxu. Ale na počítačích k tomu určených (nejlépe bez cache) a operačních systémech k tomu určených (Vxworks, Qnx apod.)."

    Jsou ruzne naroky na real-time. Pro realtime audio vyhovuje latence ~2ms, coz na Linuxu lze, ale pouze za predpokladu, ze si vsechny aplikace v audio retezci daji pozor prave na denormals.
    Navic napr. takovy LinuxSampler bych na pocitaci bez cache asi zazit nechtel.
  • 16. 2. 2009 16:36

    Biktop (neregistrovaný)
    No tak různé... Buď dobu zpracování _obecně_ na dané platformě zaručit lze (přesně nebo horním limitem), nebo ne. Pokud ne, tak se o real-time nejedná. Tak prosté to je.
  • 16. 2. 2009 17:11

    ToM (neregistrovaný)
    Bohužel si řada lidí pod pojmem real-time systém představuje spíš "rychlý" systém a netuší, že nejde ani tak o ten vlastní čas, jako spíš právě o (ne)existenci horní meze.
  • 16. 2. 2009 20:24

    Suchý čert
    Tak ale dnes se celkem běžně používá dělení na hard real-time a soft real-time, kde právě u toho druhého tu dobu zpracování obecně zaručit nelze (ale můžeme si např. experimentálně změřit, v kolika procentech případů nestihneme to zpracování dokončit včas a na základě toho se rozhodnout, zda je to pro naše účely dostačující, nebo ne).
  • 16. 2. 2009 21:44

    anonymní
    Jestli to spravne chapu, tak Molnarovy realtime-preempt patche (ktere pouzivam) zarizuji presne ten horni limit. Mam v Jacku nastavenou latency 1.33ms (2.66 InOut) a nemam xruny. Mam nalezeny hardware se kterym to funguje (to chvilku trvalo). Pro mne to je realtime. Bouchnu do klavesy, zvuk je bez spozdeni, brnknu na kytaru, zvuk je bez spozdeni. Vic "real" ten cas nepotrebuju :-)
  • 16. 2. 2009 17:35

    BLEK. (neregistrovaný)
    No, když ti real-time audio nestihne tu 2ms deadline --- tak co? Tak ti v té nahrávce cvakne.

    Na druhou stranu, kdyby nestihnutí deadline mělo vést k pádu letadla, smrti člověka nebo výbuchu nějakého zařízení, tak tam Linux být nemůže --- ten linuxový kernel nemáš šanci zkontrolovat, že se tam nikde nedrží spinlock a nescheduluje po dobu 2ms (velmi pravděpodobně tam takové místo je) --- musí tam místo toho být jiný kernel, který je pomalý, jednoduchý, primitivní, bez featur --- ale který na rozdíl od Linuxu jde zkontrolovat, že tam nejsou zakázané interrupty nebo schedulování déle než předepsanou dobu.
  • 16. 2. 2009 20:17

    VM (neregistrovaný)
    Pokud to má mít opravdu jednoduchou funkci a být spolehlivé, tak se tam dá jednoúčelový kontroler, a počítač s Linuxem až za to. V opravdu kritických aplikacích je vhodné jej zdvojit.

    Pro Linux existuje real-time patch, který by měl vyřešit základní problémy typu schedulování. S ním by real-time procesy měly teoreticky mít nízkou latenci i na vytíženém systému. Je ovšem nutné otestovat ji v praxi.

    Problém bývá s hardware. Například nějaké BIOSy mají tendenci občas na zlomek vteřiny přepnout procesor do systémového módu, ve kterém se OS vůbec nedostane ke slovu. Na takovém hardware pak můžete na real-time zapomenout.
  • 16. 2. 2009 21:50

    vtech (neregistrovaný)
    Kdyz to nestihne, tak hodi XRun, coz se s MAudio Delta 1010LT, nv ovladaci a rt-preempt kernelem nedeje. Jack to hned hlasi (i kdyz je ticho, takze by sis cvaknuti nevsimnul), takze se system dobre ladi. Je ale pravda, ze musis dat bacha na hardware. NVidia ovladace = zlo, IBM ServerRAID = zlo (kupoval jsem si kvuli nemu board s PCI-X a ted tam mam potupne SATA disky :-( ).

    Jo a dovolil bych si tvrdit, ze v nekterych nahravkach by mne cvaknuti stvalo vic, nez pad nakyho letadla :-D (Kdyz to clovek zahraje konecne po 50ty bez chyby)
  • 16. 2. 2009 14:09

    BLEK. (neregistrovaný)
    Procesor nemá osobnost.

    Na Linux máš syscall personality(). Porucha osobnosti tím ale nastavit nejde.
  • 17. 2. 2009 23:05

    bez přezdívky
    O procesorech nic nevim, ale kompilatory jiz dosahly takoveho stupne vyvoje ze jsou `poruchy osobnosti' schopny:
    
    
    ~> gcc malfunction.cc
    /tmp/ccohDlGj.o:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
    collect2: ld returned 1 exit status
    ~> gcc --version
    gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-27)
    Copyright (C) 2006 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
  • 17. 2. 2009 23:36

    bez přezdívky
    Taky jsem si to tak nejdriv vysvetloval. Nez jsem to spusitl na GAIE. 1000 taktu je na me nejak moc. Nemuzu uverit tomu ze by to bylo implementovano mikrokodem.

    A i kdyz je GAIA Intel tak nemyslim ze by to RDTSC zmeril nejak zvlast blbe. Na add daval rozumny hodnoty a koneckoncu kdyz meri ted wall time tak 1000 taktu jakekoliv periody je zkratka hodne.

    Asi mam malou fantazii ale nedokazu si predstavit co by tam mohli delat takovou dobu. I kdyby to cislo sestavovali po jednotlivych bitech tak by to melo byt const*80 taktu, kde const <=4.

    S real-time souhlasim, ovsem i soft real time (coz vlastne striktne neni realtime) dokaze nemile prekvapit kdyz bude znicehonic 1000* pomalejsi....

    "Pokud tedy návrhář procesoru může zrychlit běžné násobení třeba o jeden takt za cenu, že zpomalí málo běžné násobení (NaN) o 1000 taktů, tak to klidně udělá, protože optimalizuje průměrnou dobu výpočtu."

    Chapal bych kdyby to bylo 1:10. Ale 1:1000 je moc. Krome toho AMD je na tom rychlosti (tradicni) FPU lepe (lepsi repeat-rate pro + a *) nez Intel a presto pocita s NaNy jen o takt dele.

    Zkratka mi Intely prijdou menecenny. Duvod proc vychazeji mirne lepsi v aplikacnich testech lezi nejspis mimo jadro procesoru. Osobne podezrivam lepsi algoritmus pro plneni cachi.
  • 16. 2. 2009 12:51

    martin (neregistrovaný)
    Jako test jednoho jadra to jde, ale ve chvili, kdy se zacne prat vice jader o pamet se muze situace dramaticky zhorsit. Muze snadno dojit k tomu, ze 4 thready na 4 jadrech bezi pomaleji nez na 1 thread na jednom jadru.

    Dalsi vec. Pokud uz se clovek pusti do rucniho assembleru a optimalizece hot-spotu, mel by v prvni rade uvazovat vektorizaci pomoci SSE a XMMx registru.
  • 16. 2. 2009 16:00

    secondary.adjunct (neregistrovaný)
    "Muze snadno dojit k tomu, ze 4 thready na 4 jadrech bezi pomaleji nez na 1 thread na jednom jadru."
    Odpustte, jestli budu vypadat hloupejsi, nez syn vesnickeho hlupaka a televizni rosnicky, ale neni tohle tak nejak intuitivne jasne kazdemu?
  • 16. 2. 2009 19:25

    Petr Tesařík
    Ne. Jde o to, že ta 4 vlákna na 4 jádrech mohou danou úlohu zpracovat pomaleji než 1 vlákno na 1 procesoru, a to i v případě, že úlohu se podařilo paralelizovat. Přitom tady samozřejmě nemluvíme o strojovém čase, ale o reálném čase.
  • 16. 2. 2009 19:23

    Erbengi (neregistrovaný)
    První test je při nastavení obou jader na Performance (2.4 GHz) a druhý na Powersave (800 MHz):

    model name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
    cpu MHz : 2401.000
    cache size : 3072 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
    cpu MHz : 2401.000
    cache size : 3072 KB
    cache_alignment : 64
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 30.326 30.325
    32bit add 1.003 0.341
    32*32->64bit imul 4.546 1.448
    0*0 imul 4.546
    64/32->32.32 div 22.474
    64bit fadd 2.133 1.036
    64bit NaN+x fadd 185.003 204.240
    64bit fmul 4.737 2.029
    64bit fdiv 21.288 20.846
    32bit load from L1-cache 0.945 pitch=4B
    typical L1-miss load 37.639 pitch=74B
    load from RAM 131.96ns 316.841 pitch=1048572B
    load from RAM 141.43ns 339.585 pitch=1048572B (1-pass cache flush)


    model name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
    cpu MHz : 800.000
    cache size : 3072 KB
    cache_alignment : 64
    model name : Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz
    cpu MHz : 800.000
    cache size : 3072 KB
    cache_alignment : 64
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 96.031 96.031
    32bit add 3.010 1.022
    32*32->64bit imul 14.341 4.560
    0*0 imul 14.361
    64/32->32.32 div 70.960
    64bit fadd 6.754 3.110
    64bit NaN+x fadd 584.048 646.763
    64bit fmul 15.000 6.090
    64bit fdiv 67.413 66.004
    32bit load from L1-cache 2.994 pitch=4B
    typical L1-miss load 54.787 pitch=74B
    load from RAM 635.47ns 508.375 pitch=1048572B
    load from RAM 660.64ns 528.512 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 19:32

    Palo (neregistrovaný)
    Tak tu su dva nase Opteronove stroje. Zaujimave je ze vysledky su dost rozdielne aj ked sa jedna o podobne masiny. Prvy je SUN druhy je noname. Upozornujem ze su sice v beznej ale tichej prevadzke (asi 6 Vservrov :-)).

    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2393.628
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2393.628
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2393.628
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2393.628
    cache size : 1024 KB
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 8.001 8.001
    32bit add 1.000 0.336
    32*32->64bit imul 3.000 1.044
    0*0 imul 3.000
    64/32->32.32 div 39.019
    64bit fadd 2.982 1.003
    64bit NaN+x fadd 4.041 1.005
    64bit fmul 4.000 1.003
    64bit fdiv 22.513 21.002
    32bit load from L1-cache 0.563 pitch=4B
    typical L1-miss load 40.074 pitch=74B
    load from RAM 147.44ns 352.923 pitch=1048572B
    load from RAM 44.62ns 106.810 pitch=1048572B (1-pass cache flush)

    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2400.041
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2400.041
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2400.041
    cache size : 1024 KB
    model name : Dual-Core AMD Opteron(tm) Processor 2216
    cpu MHz : 2400.041
    cache size : 1024 KB
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 8.001 8.001
    32bit add 1.000 0.336
    32*32->64bit imul 3.000 1.044
    0*0 imul 3.000
    64/32->32.32 div 39.018
    64bit fadd 2.982 1.003
    64bit NaN+x fadd 4.041 1.005
    64bit fmul 4.000 1.003
    64bit fdiv 22.513 21.002
    32bit load from L1-cache 0.563 pitch=4B
    typical L1-miss load 30.591 pitch=74B
    load from RAM 94.80ns 227.535 pitch=1048572B
    load from RAM 20.35ns 48.848 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 19:39

    Palo (neregistrovaný)
    Ked to tak porovnam s tym 3GHz Xeon-om a 4MB chache stale si dovolim tvrdit ze bezny web serving s Javou pojde na tom 2.4 GHz Opterone rychlejsie. Ma niekto nejaky lepsi benchmark? Kedysi (uz to budu 3 roky) sme robili porovnania AMD s Intelom a AMD vtedy vyslo rychlejsie na Javu.
  • 16. 2. 2009 22:45

    drakor (neregistrovaný)
    drak@compik64:~$ cpubench
    model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5400+
    cpu MHz : 2805.766
    cache size : 512 KB
    cache_alignment : 64
    model name : AMD Athlon(tm) 64 X2 Dual Core Processor 5400+
    cpu MHz : 2805.766
    cache size : 512 KB
    cache_alignment : 64
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 8.001 8.001
    32bit add 1.000 0.336
    32*32->64bit imul 3.000 1.044
    0*0 imul 3.000
    64/32->32.32 div 39.098
    64bit fadd 2.962 1.003
    64bit NaN+x fadd 4.041 1.005
    64bit fmul 4.000 1.003
    64bit fdiv 22.513 21.002
    32bit load from L1-cache 0.563 pitch=4B
    typical L1-miss load 30.450 pitch=74B
    load from RAM 83.75ns 234.977 pitch=1048572B
    load from RAM 87.86ns 246.523 pitch=1048572B (1-pass cache flush)
  • 16. 2. 2009 23:20

    PACi (neregistrovaný)
    model name : Intel(R) Atom(TM) CPU 230 @ 1.60GHz
    cpu MHz : 1596.121
    cache size : 512 KB
    model name : Intel(R) Atom(TM) CPU 230 @ 1.60GHz
    cpu MHz : 1596.121
    cache size : 512 KB
    AVG CPU CLOCKS FOR DEPENDENT INDEPENDENT
    rdtsc 30.021 29.021
    32bit add 1.000 0.508
    32*32->64bit imul 6.018 9.020
    0*0 imul 6.018
    64/32->32.32 div 49.092
    64bit fadd 5.110 2.055
    64bit NaN+x fadd 388.991 412.490
    64bit fmul 5.000 2.058
    64bit fdiv 71.190 71.006
    32bit load from L1-cache 2.504 pitch=4B
    typical L1-miss load 33.449 pitch=74B
    out of memory !

    skoncilo ot nejak divne... :-(
  • 17. 2. 2009 14:32

    bez přezdívky
    Asi bylo malo volne pameti.
    
    
    netbook AMILO Ui3520 (fujitsu-siemens)
    
    model name      : Intel(R) Atom(TM) CPU N270   @ 1.60GHz
    cpu MHz         : 1600.970
    cache size      : 32 KB   
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      30.021       29.021  
          32bit         add         1.000        0.508  
          32*32->64bit  imul        6.082        9.143  
                   0*0  imul        6.082
          64/32->32.32  div        49.748
          64bit         fadd        5.110        2.055
          64bit  NaN+x  fadd      393.982      415.798
          64bit         fmul        5.000        2.058
          64bit         fdiv       72.115       71.006
        32bit load from L1-cache    2.504    pitch=4B 
        typical L1-miss load       34.159    pitch=74B
        load from RAM  245.08ns   392.362    pitch=1048572B
        load from RAM  217.02ns   347.437    pitch=1048572B (1-pass cache flush)
      OLD VERSION READ-TEST:
        32bit load from L1-cache    2.004    pitch=4B
        typical L1-miss load       17.336    pitch=74B
        load from RAM  126.31ns   202.212    pitch=1048572B
        load from RAM  104.41ns   167.162    pitch=1048572B (1-pass cache flush)
    
    
    ten test potrebuje zhruba 700MB volne ramky.
  • 17. 2. 2009 9:44

    obrys
    Posílám info z Phenoma. Hlásí se jako 1.2GHz, mělo by se hlásit jako 2.4GHz...
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc      70.117       69.423
          32bit         add         0.999        0.336
          32*32->64bit  imul        3.000        1.044
                   0*0  imul        3.000
          64/32->32.32  div        47.025
          64bit         fadd        2.981        0.998
          64bit  NaN+x  fadd        4.039        0.999
          64bit         fmul        3.999        0.998
          64bit         fdiv       22.473       20.996
        32bit load from L1-cache    0.558    pitch=4B
        typical L1-miss load       28.557    pitch=74B
        load from RAM  207.36ns   248.828    pitch=1048572B
        load from RAM  219.43ns   263.318    pitch=1048572B (1-pass cache flush)
    
    jenom k té první hodnotě rdtsc: Toto je nejnižší hodnota, které se mi podařilo dosáhnout jen jednou, jinak tam lítá:
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
    model name	: AMD Phenom(tm) 9750 Quad-Core Processor
    cpu MHz		: 1200.000
    cache size	: 512 KB
    cache_alignment	: 64
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc     116.031      116.016
          32bit         add         1.999        0.672
          32*32->64bit  imul        3.000        2.089
                   0*0  imul        3.000
          64/32->32.32  div        47.019
          64bit         fadd        2.980        0.992
          64bit  NaN+x  fadd        4.038        0.993
          64bit         fmul        3.998        0.992
          64bit         fdiv       22.472       20.991
        32bit load from L1-cache    0.547    pitch=4B
        typical L1-miss load       28.549    pitch=74B
        load from RAM  203.72ns   244.469    pitch=1048572B
        load from RAM  217.87ns   261.446    pitch=1048572B (1-pass cache flush)
    
    Nijak jsem neořezával procesy... Mám spuštěnej desktop s běžnými programy, je možné, že to někde něco brzdí.

    Obrys
  • 17. 2. 2009 17:21

    anonymní
    tech 1200 misto 2400 je kvuli snizovani frekvence, mel byste pred testem pouzit performance governor

    to plati asi pro vsechny, jinak merite tez latence pri postupnym zvysovani frekvence
  • 17. 2. 2009 18:35

    bez přezdívky
    Nejde o to, že mají 400x ale jde o řád, tudíž, že je to 100x (dva řády), význam má snížit latenci v rámci řádů, což se jen tak nepovede. Má někdo DDR3 nebo snad ještě něco lepšího jako systémovou RAM?
  • 17. 2. 2009 22:34

    bez přezdívky
    Jeste jsem zmeril nasledujiciho "dedecka". Musel jsem pochopitelne zmensit velikost bloku, protoze mel jen 128MB pameti:
    
    
    model name      : AMD-K6(tm) 3D processor
    cpu MHz         : 300.745
    cache size      : 64 KB  
          AVG CPU CLOCKS FOR    DEPENDENT    INDEPENDENT
                        rdtsc       9.011        7.681  
          32bit         add         1.000        0.556  
          32*32->64bit  imul        3.043        3.177  
                   0*0  imul        3.043
          64/32->32.32  div        20.292
          64bit         fadd        3.050        3.006
          64bit  NaN+x  fadd        7.126        7.008
          64bit         fmul        3.000        3.006
          64bit         fdiv       40.632       41.432
        32bit load from L1-cache    1.061    pitch=4B 
        typical L1-miss load       95.363    pitch=74B
        load from RAM  688.83ns   207.162    pitch=1048572B
        load from RAM  223.15ns    67.112    pitch=1048572B (1-pass cache flush)
     OLD VERSION READ-TEST:
        32bit load from L1-cache    2.283    pitch=4B
        typical L1-miss load       47.693    pitch=74B
        load from RAM  360.69ns   108.475    pitch=1048572B
        load from RAM  111.43ns    33.512    pitch=1048572B (1-pass cache flush)
    
    
  • 17. 2. 2009 23:50

    romero (neregistrovaný)
    Co tak spravne poukladat data? Ale az mi je divne kolko malo programatorov to napadne. Ale to lamky nevedia. A preco by sa to aj ucili. Ved ich ani nenapadne si svoj genialny vytvor obenchmarkovat. A ked na nich vyletis ze ich funkcia zere 80% vykonu na cumia jak telata. Co nespravis sam, to stoji za hovno. Tolko moja skusenost v praci. PEACE OUT
  • 18. 2. 2009 23:39

    limit_false (neregistrovaný)
    V prvni rade diky za clanek, v posledni dobe na rootu moc technickych clanku neni.

    Zajimalo by mne na ktere typy uloh je mozne uplatnit tenhle low-level typ profilingu? I kdyz obdivuju hacky typu "Cormackova" inverse square rootu s 0x5f3759df, prijde mi ze to jde uplatnit jenom ve velmi specifickych podminkach:

    1. Musite psat aplikaci "from scratch" (aby bylo mozne zvolit vsechny datove struktury)
    2. Hotspoty musi byt zalozeny hlavne na aritmetice (treba grafika je celkem dobry priklad; bitva s memory alokatorem kvuli cache-miss je masakr, viz nize)
    3. Nesmite prilis pouzivat 3rd-party knihovny (nejvic nekolik), protoze nevite "co kde lita" a hrabat se v nich/prepsat to treba z casovych duvodu nejde
    4. Nesmi to byt multiplatformni (prekladacem vygenerovany kod na vsech platformach neuhlidate)

    Konkretni zkusenost: multiplatformi (linux/windows) prekladac v C++, typicke struktury jsou grafoveho charakteru a mapy - syntakticky strom, tabulky symbolu, apod. Pouziva celou armadu knihovnen typu xerces, boost... Cilem je udelat existujici kod rychlejsi.

    Tohle jsou nejake typicke bottlenecky a postrehy pro tenhle pripad:
    1. "Nevyjimecne" pouziti vyjimek (=nekolik desitek/stovek) umi spolehlive zabit dobry algorimus, specialne se starsi glibc a hazenim pres hranici knihoven
    2. Pouziti std::algorithm a boost::lambda byva rychlejsi (i dvojnasobne) nez "emulovani" pres for/while (zavisi jak moc prinutite C++ prekladac inlineovat kratke funkce)
    3. std::map a std::set jsou paradoxne rychlejsi nez hash_map a hash_set navzdory O(log(n)) vs O(1) pro male mapy/sety (< 1000 polozek). Na tomhle ma nejspis zasluhu C0x standard, ktery pozaduje lokalni iteratory na buckety=> implementace nemuze byt open-adressing (=>extra mallocs => extra cache misses). boost::unordered_set a boost::unordered_map jsou (mirne) lepsi nez hash_set a hash_map, ale pro male sety/mapy je lepsi pouzit std:: verze (zalozeny na RBtree)
    4. msvc ma pomaly malloc/free/new/delete, mirne rychlejsi exception unwinding nez gcc+glibc (se starsi glibc 2.3.x jsou ty vyjimky hodne spatny). reserve() muze vyrazne pomoci kdyz vite kolik veci nasypete do STL kontejneru
    5. U gcc dokaze obrovske mnozstvi cyklicky vytvarenych a mazanych mensich hash_setu/hash_map udelat celkem brutalni memory fragmentation (napr. skutecne mate naalokovano 20MB, jenze kvuli fragmentaci je namapovano pro proces klidne 200 MB RSS)
    6. Kdyz zacnete pouzivat 3rd party knihovny, budete se celkem divit, ze dve podobny funkce jsou implementovany uplne jinak (jedna je rychla a ta druha to zabije); obcas se oplati malou cast preimplementovat
    7. I kdyz se pri slozitosti konstanta ignoruje, pri profilingu na ni k*va zalezi ;-)

    Slo by low-level pristup z clanku aplikovat nejak v tomhle pripade? (tam hlavne nevite jak to nejaka knihovna rozhazi po pameti) Treba by slo napsat si vlastni memory allocator nebo pouzit nejaky page coloring kernel patch (jenze v prvnim pripade to neni uplne sranda a druhym pripade tezko presvedcite uzivatele pouzit kernel patch, ktery muze zmrvit vykon ostatnich veci).

    BTW: pouzivame NaN ve specialnich pripadech matematickych funkci jako hodnotu "undef" (funkce v bode nedefinovana, testovano je to porovnanim). Bohuzel jsem nemel cas zatim zmerit, jestli by se to zrychlilo pouzitim treba numeric_limits<double>::max misto NaN. (Podival jsem se na implementaci finite() a ta to dela bitovou maskou => FPU exception nemuze nastat)
  • 19. 2. 2009 9:07

    klusacek (neregistrovaný)
    "Slo by low-level pristup z clanku aplikovat nejak v tomhle pripade? (tam hlavne nevite jak to nejaka knihovna rozhazi po pameti)"

    To si nejsem jisty. Ja osobne pouzivam pouze libc a libm. Ostatni si pisu.


    Nicmene podobny low-level pristup je pouzity v knihovne fftw (FFT na 1000 zpusobu), ovsem ponekud brutalne. Na druhou stranu je to (snad porad) nejrychlejsi implementace FFT a dokonce multiplatformni (toho dosahuji tak ze parametry (a dokonce poskladani kusu kodu ktere FFT implmementuji) se doladuji behem kompilace na target machine nebo dokonce za behu (v inicializaci)).


    V high-level se to da pouzit jen omezene pri navrhu. Treba kdyz mate nejaky AI program ktery nejprve treba neco pocita pomoci SVM (nebo neuronovych siti) a nasledne s temi vysledky provadi A^* algoritmus tak na starsich pocitacich, ktere mely pomalou aritmetiku a relativne rychle pristupy do pameti bylo lepsi udelat jednodussi SVM a narocnejsi A^*. Dnes je to naopak. Tedy za predpokladu ze celkova uspesnost toho programu se da balancovat mezi SVM a A^*.
  • 19. 2. 2009 19:55

    vid (neregistrovaný)
    Fuj, AT&T syntax :)
    Ale inak fajn clanok, niekedy je zaujimave neverit manualom a pozriet sa na vec v praxi. Len este k tomu co napisali ostatni par detailov:

    > Takových instrukcí je sto, pak je skok na začátek, opakujeme pětsetkrát (důvod pro opakování je případné vyprůměrování doby, kdy se instrukce načítaly do instrukční cache)

    pre nacitanie do instrukcnej cache staci kod alignovat na co najokruhlejsej hranici, a potom ho pred samotnym meranim 1x nechat prebehnut. Pri dalsom behu uz bude v instruction cache.

    > Přesnějšího měření by bylo možné dosáhnout při zakázaném přerušení, ale nevím, co by se pak stalo při případném page-faultu (jestli by si Linux přerušení zase povolil, kdyby třeba potřeboval mmapovat program z disku nebo swapovat, čemuž by se částečně dalo předejít zamknutím stránek v RAM). Pak by mělo smysl výsledky z jednotlivých opakování průměrovat. Jelikož jsem ale nechtěl riskovat zamrznutí systému a na většině měřených počítačů stejně nejsem root, dále jsem tento problém neřešil.

    1. Neviem co presne urobi zakazanie preruseni v user mode v Linuxe (zalezi ako linux nastavil IOPL), ale dost pochybujem ze by vyvojari linuxu boli taki sprosti aby ho normalne povolili. Ved to by potom mohol ktorykolvek program zablokovat cely system.

    2. (aj pre p. Tesarika) Zakazanie preruseni (STI) nezakazuje vynimky, takze page fault sa handluje normalne aj pri IF=0.

    Este k tomu co sa pisalo v inych komentaroch:

    > a jak se lisi ruzne kompilery co se tyka vyuziti ruznych registru, aby se instrukce
    staly nezavislymi a dalsi chytre zmeny v kodu ktere provede kompiler ???

    Ohladne C kompilatorov: Zevraj najlepsi je Intelacky kompilator, aj co som videl ukazky dokaze dost drsne paralelizovat instrukcie, aj ked to nieje este celkom dotiahnute. Co som pozeral kod tak MSVC and GCC su tak zajedno, obidva dobre. Osobne mi viac sedel MSVC, pri GCC sa mi zdalo ze tam defaultne hadze vela zbytocneho svinstva, ale mozno je to len tym ze MSVC viem lepsie pouzivat. Ostatne by som radsej nepouzival.

    > Nicmene s tou TLB jste me privedl na myslenku, ze vlastne netestuju dobu
    pristupu k pameti ale nejmene dobu 2 pristupu, protoze nejspis temer vzdy
    vypadnu z TLB.

    Samotne precitanie polozky zo strankovacej tabulky su v zavislosti od typu strankovania 2-4 pristupy do pamate. 4 ale len v IA32e resp. long mode.

    > Nemáte někdo přístup k počítači, kde je gcc i icc? Moc by mě zajímalo srovnání, jestli to intel optimalizuje na svoje procesory lépe. Tvrdí se, že na čísla bývá o pár procent nebo desítek procent rychlejší.

    Ja mam obidva, ale nejak som to zatial neskusal. Ale co som videl ukazky na internete, ak je ten intelacky kompilator dobre nastaveny, dokaze take veci o ktorych sa msvc alebo gcc ani nesniva.

    > Zajimalo by mne na ktere typy uloh je mozne uplatnit tenhle low-level typ profilingu?

    V podstate na vsetky, kuknes co ti vyliezlo z kompilatoru a rozmyslas ako by to islo spravit lepsie. Ale to by bolo nehorazne vela roboty. Otazka by skor mala zniet na ktore casti programu MA ZMYSEL tento typ profilingu uplatnit. A tam je to jasne:
    1. Ma to cele zmysel iba ak program naozaj potrebuje urychlit
    2. Ma to zmysel len na bottleneckoch programu, aj to len v pripade ze program je CPU/RAM bound. Pri hrach sa pokail viem vecsinou caka na GPU, pri vecsine programov na disk alebo co, a tam takato optimalizacia nic neriesi.

    Typicky priklad kde to ma zmysel su vypoctovo narocne veci - neuronove siete, simulacie typu Folding@home, atd.

    A ze je problem vypat strankovanie pod operacnym systemom: nesuhlasim, podla mna to skoro vobec nieje problem, akonahle uz raz si v kernel kode. Staci si v alokovat kus identity-mapped pamate (windows to vie urcite a linux IMO musi tiez, napriklad DMA to tusim vyzaduje), nakopcit do nej svoj position-independent kod, skocit nan a vypat strankovanie - nic sa nedeje.
  • 20. 2. 2009 8:35

    bez přezdívky
    > Fuj, AT&T syntax :)

    No jo, Stallmanova oblibena. Asi mel rad M 68k. Podle me je to blbost, protoze pak se tezko pouziva kod urceny pro jine kompilatory. Syntax ma byt takova jakou pouziva vyrobce CPU. Ale poucili se, napr. ARM ma na gcc temer uplne standardni syntax.

    > pre nacitanie do instrukcnej cache staci kod alignovat na co najokruhlejsej hranici,

    Ono se to opakuje nejen kvuli cache, ale taky aby se vyprumerovala RDTSC instrukce, ktera na intelu trva 100 taktu. Sice se jeji efekt snazim odcitat, ale je to k nicemu, protoze neni zaruceno kdy presne se provede (out-of-order execution). Skoro soudruhy od Intelu podezrivam ze implmentovaly TSC jako citac se seriovym prenosem aby usetrili. Kdyz pak chteji chytnout jeho hodnotu tak musi mit druhy registr do ktereho to kopiruji bit po bitu (LSB first), kazdy takt jeden bit (aby dostali spravnou hodnotu i kdyz nastal prenos). To by trvalo 64 taktu a ten zbytek uz jsem ochoten verit ze trva mikrokodu nez to dopravi do edx:eax.

    > 2. (aj pre p. Tesarika) Zakazanie preruseni (STI) nezakazuje vynimky, takze page fault sa handluje
    > normalne aj pri IF=0.

    To jiste ano, ale kdyz to dopadne jako cteni stranky z disku tak disk oznamuje ukonceni DMA prerusenim. Mohli by sice na nej cekat ve smycce, ale to by tam pak musely byt 2 ruzne kody cteni te stranky jeden pro IF=0 a druhy pro IF=1. To se mi nechce moc verit. Myslim si, ze bud to nebude fungovat vubec (vytuhne), nebo si to preruseni povoli. Urcite to tu nejaky kernel guru bude vedet....


    > A ze je problem vypat strankovanie pod operacnym systemom...

    To je problem protoze na takovou vec bych musel byt root (coz na vetsine testovanych pocitacu nejsem).


    > Samotne precitanie polozky zo strankovacej tabulky su v zavislosti od typu strankovania 2-4 pristupy
    > do pamate. 4 ale len v IA32e resp. long mode.

    Predpokladejme ze nejsem v long modu. Pak je treba nacist GDT a LDT, ale pitch neni zase tak veliky aby se pozice v GDT moc menila, takze se GDT se dostane rychle do cache (pokud je tam aspon nejaky preread) a pak uz je to jen 1 pristup do LDT. Aspon si to tak predstavuju.
  • 23. 2. 2009 12:45

    vid (neregistrovaný)
    > Skoro soudruhy od Intelu podezrivam ze implmentovaly TSC jako citac se seriovym prenosem aby usetrili.

    Od urcitej rady (uz neviem ktorej) TSC uz nepocita cykly CPU, ale len sa veselo inkrementuje nezavisle od CPU. Myslim ze kvoli tomu aby bola zarucena viacmenej rovnaka rychlost pripocitavania na viacerych jadrach aj ked jedno z nich chvilu idlovalo. Pre zaujimavost, u mna na CoreDuo sa TSC pripocitava zasadne v nasobkoch 10 :)

    > To jiste ano, ale kdyz to dopadne jako cteni stranky z disku tak disk oznamuje ukonceni DMA prerusenim.

    To je pravda, dobry postreh :)

    > Myslim si, ze bud to nebude fungovat vubec (vytuhne), nebo si to preruseni povoli. Urcite to tu nejaky kernel guru bude vedet....

    Ako som pisal, najskor proste nastavi IOPL na hodnotu mensiu ako 3, po com STI/CLI bude pristupovat k VIF a nie k IF. Ale kazdopadne, urcite nedovoli usermode aplikacii pristupit k IF, to by bolo chore.

    >> Samotne precitanie polozky zo strankovacej tabulky su v zavislosti od typu strankovania 2-4 pristupy do pamate. 4 ale len v IA32e resp. long mode.

    > Predpokladejme ze nejsem v long modu. Pak je treba nacist GDT a LDT, ale pitch neni zase tak veliky aby se pozice v GDT moc menila, takze se GDT se dostane rychle do cache (pokud je tam aspon nejaky preread) a pak uz je to jen 1 pristup do LDT. Aspon si to tak predstavuju.

    Tu si asi nieco pleties. Do GDT pri pristupe do pamate nieje preco pristupovat (ak myslis ze kvoli segment base, tak nie, ta sa uklada do zvlast registra uz pri nastaveni selektoru). Pristupuje sa do strankovacich struktur, teda ak nieje adresa v TLB tak su to 1 alebo 2 extra pristupy do pamate pri klasickom strankovani (podla toho ci je stranka 2MB alebo 4KB), 2 az 3 extra pristupy pri PAE-36 strankovani, 1 extra pristup pri PSE-36 strankovani, a 3 az 4 extra pristupy pri PAE-64 strankovani.
  • 23. 2. 2009 20:27

    klusacek (neregistrovaný)
    > Tu si asi nieco pleties. Do GDT pri pristup....

    No jasne, to jsem blabolil. Myslel jsem page-directory a page-table.


    Jinak TSC se tu probiralo v jinych prispevcich. Je skoda ze to takhle znicili, byla to docela uzitecna vec.
  • 24. 2. 2009 1:08

    vid (neregistrovaný)
    Na tych inteloch kde to znicili uz mas performace monitoring, ktory je vraj ovela preciznejsi. Ale este sa tomu nevenoval a neviem ti zodpovedne povedat nakolko to vie merat rychlost relativne maleho kusu kodu.

    Len viem ze samotne koncepcia poctu CPU cyklov ktore kod trva, je uz v dnesnych procesoroch dost fiktivna, kedze mas veci ako out-of-order execution atd. Tak sa netreba cudovat ze spravili to co spravili.

    Ale tak celkovo s tebou suhlasim, bola to sikovna vecicka, len uz jej doba skoncila.