abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
včera 16:33 | Komunita

Google zveřejnil seznam 200 organizací přijatých do letošního Google Summer of Code (GSoC). Dle plánu se studenti přihlašují od 16. do 31. března. Vydělat si mohou od 3 000 do 6 600 dolarů. V Česku a na Slovensku 3 600 dolarů. Další informace v často kladených otázkách (FAQ). K dispozici jsou také statistiky z minulých let.

Ladislav Hagara | Komentářů: 0
včera 15:55 | IT novinky

Ve věku 74 let zemřel Lawrence Tesler. V 70. letech pracoval v Xerox PARC a posléze odešel do Apple. Zabýval se především zjednodušováním uživatelských rozhraní, byl odpůrcem modality a přispěl k prosazení moderního způsobu označování a kopírování textu – myší a klávesovými zkratkami (kombinace s XCV) – v raných Apple Human Interface Guidelines. Dále se podílel např. na vývoji Smalltalku a souvisejícího přenosného počítače Xerox NoteTaker nebo později PDA Apple Newton.

Fluttershy, yay! | Komentářů: 1
včera 13:11 | Zajímavý článek

Aktuální příspěvek What is Mobile PureOS? na stránkách společnosti Purism je věnován operačnímu systému Mobile PureOS, tj. PureOS pro mobilní zařízení a především pro telefon Librem 5. Víceméně se jedná o stabilní Debian s GNOME doplněný o balíčky phosh, phoc, libhandy, Calls, Chats a další.

Ladislav Hagara | Komentářů: 0
20.2. 19:33 | Zajímavý článek

Jozef Mlich se v příspěvku PinePhone je nové OpenMoko na svém blogu věnuje svému novému linuxovému chytrému telefonu PinePhone v edici BraveHeart: "Momentálně se pocity z tohohle zařízení dají přirovnat k BrokenMoku. Většina věcí prostě nefunguje. Minimálně ne sama od sebe. Začít se dá už u samotného hardware, kde existuje wiki stránka popisující nedostatky".

Ladislav Hagara | Komentářů: 15
20.2. 10:00 | Zajímavý projekt

Justine Haupt aktualizovala svůj open source mobilní telefon s rotační číselnicí a zveřejnila kompletní dokumentaci, vlastní kód, schémata i STL soubory pro 3D tisk. Desku plošných spojů případně i vytištěný obal lze koupit v jejím obchodu.

Ladislav Hagara | Komentářů: 34
20.2. 06:00 | IT novinky

Otevřená certifikační autorita Let's Encrypt v příspěvku na svém blogu informuje, že žádosti o vystavení certifikátů nově validuje z několika míst současně (Multi-Perspective Validation). Další informace v diskusním fóru.

Ladislav Hagara | Komentářů: 10
19.2. 13:55 | Nová verze

Byla vydána verze 15.0 na Debianu založené linuxové distribuce Untangle NG Firewall. Přehled novinek v poznámkách k vydání a ve videu na YouTube. Vyzkoušet lze (zatím neaktualizované) demo webového rozhraní.

Ladislav Hagara | Komentářů: 0
19.2. 12:11 | Pozvánky

Letošní ročník konference LinuxDays se uskuteční o víkendu 3. a 4. října, opět se potkáme v pražských Dejvicích na FIT ČVUT. Také během devátého ročníku nás budou čekat desítky přednášek, workshopy, stánky a spousta doprovodného programu. Aktuální dění můžete sledovat na Twitteru nebo Facebooku, přidat se můžete také do telegramové diskusní skupiny.

Petr Krčmář | Komentářů: 7
19.2. 10:22 | Zajímavý článek

Alexander Popov se v příspěvku na svém blogu podrobně věnuje možnostem zneužití bezpečnostní chyby CVE-2019-18683 v linuxovém podsystému V4L2. Videoukázka eskalace práv na YouTube. Chyba byla v upstreamu opravena v listopadu loňského roku. Alexander Popov se chybě věnoval ve své přednášce (pdf) na konferenci OffensiveCon 2020.

Ladislav Hagara | Komentářů: 0
19.2. 06:00 | Nová verze

Byla vydána nová verze 20.02.17 svobodného multiplatformního video editoru Shotcut (Wikipedie). Přehled novinek v oznámení o vydání. Využíván je MLT Multimedia Framework 6.20.0 a WebVfx 1.2.0. Nejnovější Shotcut je k dispozici také ve formátech AppImage, Flatpak i Snap.

Ladislav Hagara | Komentářů: 2
Vydržela vám novoroční předsevzetí?
 (9%)
 (6%)
 (3%)
 (82%)
Celkem 173 hlasů
 Komentářů: 0
Rozcestník

Jednoduchý benchmark pro memcpy()

28.5.2007 15:08 | Přečteno: 2017× | Programování | Výběrový blog | poslední úprava: 28.5.2007 18:33

Tímto reaguji na tento zajímavý blogpost. V diskusi zaznělo, že by bylo dobré udělat benchmark. Jenže kdo by ho měl udělat? Tak jsem se nakonec rozhodl, že to zkusím. Myslím si, že následující údaje stojí za přečtení a zamyšlení.

Co, proč a jak jsem testoval

Zajímala mě rychlost fungování různých typů kopírování dat v paměti. Chtěl jsem zjistit, jaký vliv má optimalizace. Nešlo mi o maximální možnou přesnost měření. Spíš jsem chtěl v rozumném čase sestavit a provést jednoduchý a pokud možno zajímavý benchmark.

Všechny testy jsem spouštěl ve stejné situaci, pokud jde o zatížení systému a ostatní procesy. Vypnul jsem náročné aplikace. Během testu jsem se zdržel veškerého uživatelského vstupu. X-server a KDE jsem ponechal v provozu. Zajímal mě standardní výkon v naprosto běžné situaci. Špičkové výkony za uměle nastolených ideálních podmínek jsem netestoval. Frekvenci procesoru jsem po dobu testu pevně nastavil na maximální hodnotu.

Použitý hardware

Můj výtečný stroj. Je to notebook Asus M2400N. Má procesor Pentium M na 1600 MHz a 512 MB RAM na 266 MHz. Použil jsem nastavení Tickless System (CONFIG_NO_HZ). Standardní frekvenci časovače mám na 300 Hz. Ještě by mohly být důležité volby CONFIG_PREEMPT=y a CONFIG_PREEMPT_BKL=y.

Použitý software

Udělal jsem malý a ošklivý prográmek na testování. Sestává z testovací knihovny, která umí měřit čas, a z vlastní definice testovacích funkcí. Dám sem všechny soubory, aby bylo případně možné je rovnou stáhnout a zkompilovat:

Výsledky testu

Jak už jsem psal, jde vždy o průměry z deseti po sobě jdoucích měření za výše popsaných podmínek. Všechny údaje jsou v milisekundách. Důležité je, jaký kompilátor byl použit:

  1. g++ -O0 (verze 4.1.2)

  2. g++ -O3 -march=pentium-m (verze 4.1.2)

  3. icpc -O0 (verze 9.1)

  4. icpc -O3 -xB (verze 9.1)

g++ (1)

g++ (2)

icpc (3)

icpc (4)

std_memcpy()

97,90

96,70

97,80

64,60

pluscpy< char >()

745,40

206,10

590,90

191,70

pluscpy< int >()

245,20

192,20

219,40

191,40

pluscpy< long long >()

205,10

191,80

202,20

191,60

endcpy< char >()

862,50

195,30

544,50

192,20

endcpy< int >()

243,60

191,40

211,40

191,40

endcpy< long long >()

200,90

191,70

201,70

191,50

spccpy< char >()

716,70

194,40

533,50

198,50

spccpy< int >()

230,80

191,40

210,90

191,60

spccpy< long long >()

201,60

191,60

198,40

192,10

Nelze si nevšimnout několika základních faktů. Ne každému se chce podrobně prohlížet celou tabulku, proto bych je tu rád shrnul.

Závěr

Kdyby někdo z vás měl trochu času nazbyt a mohl by něco podobného jen tak pro zajímavost vyzkoušet na jiné architektuře, popřípadě s kompilátorem Sun, jistě by to nebylo na škodu. Nebo se můžete pochlubit nějakým hustým strojem, který dosáhne srovnatelných čísel s desetkrát větším kopírovaným blokem. :-) Tak co vy na to?

Snad tento benchmark aspoň aspoň zčásti odpovídá na otázky kolem tohoto blogpostu.

       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

rADOn avatar 28.5.2007 15:58 rADOn | skóre: 44 | blog: bloK | Praha
Rozbalit Rozbalit vše Zaver II:
kdyby si komentujici precetli neco k tematu ( treba http://www.lysator.liu.se/c/duffs-device.html ) mohlo byt na svete zase o par kilobyte zbytecnych reci mene.
"2^24 comments ought to be enough for anyone" -- CmdrTaco
28.5.2007 16:04 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Zaver II:

To sice jo, ale i dávno vyřešené věci někdy neuškodí prodiskutovat znova. Právě proto, že se řešily dávno.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 16:22 VM
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Zdravim, abyste mel ze sve prace malinko radost a ukojil Vasi touhu po rychlejsim stroji, tak zde jsou velmi rychle vysledky z PowerPC platformy(bez zadnych zmen v kodu).
pocitac: IBM p550-v lparu je dedikovan 1 dualcorovy p5+ procesor
suse-tftp:/tmp/memtest # cat /proc/cpuinfo
processor       : 0
cpu             : POWER5+ (gs)
clock           : 1648.350000MHz
revision        : 3.1 (pvr 003b 0301)

processor       : 1
cpu             : POWER5+ (gs)
clock           : 1648.350000MHz
revision        : 3.1 (pvr 003b 0301)

timebase        : 512365000
machine         : CHRP IBM,9133-55A

suse-tftp:/tmp/memtest # cat /etc/SuSE-release
SUSE Linux Enterprise Server 10 (ppc)
VERSION = 10

g++
optimalizace: -Wall -O3  -pipe
Average time: 33.70

bez optimalizace:
Average time: 160.10

28.5.2007 16:48 VM
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Prace kvapna malo platna(zajimavy je memcpy test). Vysledky z predchozi konfigurace:
G++ (bez optimalizace)
-----------------------
Standard memcpy()                               Average time: 45.90
Offset-driven copy test (bytes)                 Average time: 1713.40
Offset-driven copy test (ints)                  Average time: 583.30
Offset-driven copy test ('long long's)          Average time: 218.60
Pointer-driven copy test (bytes)                Average time: 1206.90
Pointer-driven copy test (ints)                 Average time: 265.40
Pointer-driven copy test ('long long's)         Average time: 156.60
Special 'modulo' copy test (bytes)              Average time: 1791.40
Special 'modulo' copy test (ints)               Average time: 390.00
Special 'modulo' copy test ('long long's)       Average time: 160.00



G++(-Wall -O3  -pipe)
--------------------------
Standard memcpy() test                          Average time: 46.10
Offset-driven copy test (bytes)                 Average time: 250.80
Offset-driven copy test (ints)                  Average time: 128.30
Offset-driven copy test ('long long's)          Average time: 39.20
Pointer-driven copy test (bytes)                Average time: 252.10
Pointer-driven copy test (ints)                 Average time: 128.40
Pointer-driven copy test ('long long's)         Average time: 39.20
Special 'modulo' copy test (bytes)              Average time: 137.30
Special 'modulo' copy test (ints)               Average time: 41.60
Special 'modulo' copy test ('long long's)       Average time: 33.60
28.5.2007 16:58 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()

Je pro mě příjemným překvapením, že ta moje slátanina šla vůbec zkompilovat a spustit na jiné architektuře. :-) Každopádně děkuji za velmi zajímavý výsledek. Knihovní memcpy je u Vás asi napsaná komplet v assembleru, když jí optimalizace škodí...

Pointer-driven copy test (ints)                 Average time: 128.40
Pointer-driven copy test ('long long's)         Average time: 39.20

Promiňte mi hloupou otázku: Ten stroj je 64-bitový? Jinak si neumím vysvětlit tak velký nárůst rychlosti při použití long long...

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 20:14 VM
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Jsem rad, ze Vas to potesilo. Ano je to RISC 64 bit. IBM_P5. A musim rici ze Vas blog trosku rozpoutal muj zajem o tuto oblast OS, neb jsem timto neposkvrnen.
28.5.2007 18:18 kl
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
G++ (bez optimalizace)
-----------------------
Standard memcpy()                               Average time: 271.10
Offset-driven copy test (bytes)                 Average time: 867.70
Offset-driven copy test (ints)                  Average time: 262.10
Offset-driven copy test ('long long's)          Average time: 180.90
Pointer-driven copy test (bytes)                Average time: 814.60
Pointer-driven copy test (ints)                 Average time: 251.10
Pointer-driven copy test ('long long's)         Average time: 182.20
Special 'modulo' copy test (bytes)              Average time: 779.50
Special 'modulo' copy test (ints)               Average time: 243.90
Special 'modulo' copy test ('long long's)       Average time: 174.20
G++ (-O2 -march=athlon-xp -pipe -mcpu=i686 -fomit-frame-pointer -msse -mmmx -m3dnow -ffast-math -fprefetch-loop-arrays 
-finline-limit=600 -ftracer)
-----------------------
Standard memcpy()                               Average time: 244.90
Offset-driven copy test (bytes)                 Average time: 998.20
Offset-driven copy test (ints)                  Average time: 287.40
Offset-driven copy test ('long long's)          Average time: 198.60
Pointer-driven copy test (bytes)                Average time: 896.50
Pointer-driven copy test (ints)                 Average time: 267.60
Pointer-driven copy test ('long long's)         Average time: 190.10
Special 'modulo' copy test (bytes)              Average time: 814.00
Special 'modulo' copy test (ints)               Average time: 258.40
Special 'modulo' copy test ('long long's)       Average time: 183.40
28.5.2007 22:04 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()

Překvapivé. U Vás není vítězem memcpy(). Jak je to možné?

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 22:16 Käyttäjä 11133 | skóre: 58 | blog: Ajattelee menneisyyttä
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
To nevím, ale je to tak :)
28.5.2007 22:32 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()

To je divné. Týká se to dokonce i 32-bitových Athlonů, jak je vidět o kus níž. Jestli se používá často memcpy i v kernelu...

[andrej@xandrej linux]$ grep -R memcpy * | wc -l
9318

...tak to je potom smutné. Takže procesory AMD asi nejsou využité tak dobře, jak by mohly být.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 23:27 Käyttäjä 11133 | skóre: 58 | blog: Ajattelee menneisyyttä
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Tak to abychom udělali vlastní fork kernelu :)
29.5.2007 13:29 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Tak to abychom udělali vlastní fork kernelu :)

A ten by spočíval v rekurzivním průchodu stromem a nahrazení všech memcpy() něčím jiným. :-D

Zjistil jsem, že kernelu se případný problém netýká. Má totiž vlastní implementaci knihoven pro každou architekturu zvlášť. Kompilují se různé jejich části podle toho, jaké možnosti má cílový procesor. Je to k vidění například zde:

[andrej@popelnice linux]$ ls arch/i386/lib/mem*
arch/i386/lib/memcpy.c
[andrej@popelnice linux]$ ls arch/x86_64/lib/mem*
arch/x86_64/lib/memcpy.S  arch/x86_64/lib/memmove.c  arch/x86_64/lib/memset.S

Používají se tam i poměrně nové sady instrukcí, takže uživatel může být klidný, že strhujícím výkonem jeho stroje nikdo neplýtvá :-D

Je tu už i měření Michala Kubečka, kde memcpy() na AMD s drtivou převahou vítězí.

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 17:10 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Kernel poměrně často potřebuje "klonovat stránky" fyzické paměti po copy-on-write faultech. Proto je v něm kopírování delších bloků slušně optimalizováno (funkce copy_page). Kopírování přes 64-bit FPU registry je rychlejší, kopírování pomocí 128-bit SSE registrů je ještě lepší. Tady jsou nějaké benchmarky.

http://lwn.net/Articles/137994/
Táto, ty de byl? V práci, já debil.
Jiří Němec avatar 28.5.2007 20:30 Jiří Němec | skóre: 22 | blog: BluPix | Horní Smrčné
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Linux Oktavo 2.6.21-viper1 #9 SMP PREEMPT Mon May 21 16:36:17 CEST 2007 x86_64 AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ AuthenticAMD GNU/Linux

Nemám dual-channel paměti :-(
1.-O0
2.-Os -march=athlon64 -msse3 -pipe
3.-O3 -march=athlon64 -msse3 -pipe
4.-O3 -march=athlon64 -mtune=athlon64 -msse3 -pipe -falign-functions=4 
-fprefetch-loop-arrays -fomit-frame-pointer
                                          1       2       3       4
Standard memcpy() test                    192.80  150.60  56.30   54.90
Offset-driven copy test (bytes)           755.40  257.70  206.80  224.60
Offset-driven copy test (ints)            222.70  108.80  94.20   73.40
Offset-driven copy test ('long long's)    132.50  88.30   71.40   70.30
Pointer-driven copy test (bytes)          707.80  207.20  204.30  224.60
Pointer-driven copy test (ints)           213.30  96.00   97.80   68.30
Pointer-driven copy test ('long long's)   128.30  76.20   73.20   66.40
Special 'modulo' copy test (bytes)        671.00  141.70  146.30  146.10
Special 'modulo' copy test (ints)         206.20  87.40   83.90   83.60
Special 'modulo' copy test ('long long's) 124.80  75.00   71.50   70.80


Spock: "Logic, logic, logic. Logic is the beginning of wisdom, not the end.
Jiří Němec avatar 28.5.2007 20:44 Jiří Němec | skóre: 22 | blog: BluPix | Horní Smrčné
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Omlouvám se, u prvního výsledku -O0 jsem ještě neměl vypnutý ondemand, místo 192 by tam mělo být 149-152. Těch 10 běhů je asi málo.
Spock: "Logic, logic, logic. Logic is the beginning of wisdom, not the end.
28.5.2007 22:16 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Těch 10 běhů je asi málo.

Taky se tu nesnažíme o nějakou velkou přesnost. ;-) Funkce test_run() má parametr repeat, kterým lze počet běhů nastavit. Taky jsem musel vypnout ondemand. :-)

Překvapuje mě, že na AMD64 není memcpy() vítězem. Není tam náhodou 32-bitový kernel nebo alespoň 32-bitové knihovny? To by bylo jediné možné vysvětlení, proč může být tento kód rychlejší než memcpy().

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
Jiří Němec avatar 28.5.2007 22:27 Jiří Němec | skóre: 22 | blog: BluPix | Horní Smrčné
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Tohle je kompletně 64bit.
ldd test
        libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu
/4.1.2/libstdc++.so.6 (0x00002b3c41d78000)
        libm.so.6 => /lib/libm.so.6 (0x00002b3c41f76000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00002b3c420cb000)
        libc.so.6 => /lib/libc.so.6 (0x00002b3c421d9000)
        /lib64/ld-linux-x86-64.so.2 (0x00002b3c41c5b000)
Spock: "Logic, logic, logic. Logic is the beginning of wisdom, not the end.
Jiří Němec avatar 28.5.2007 21:58 Jiří Němec | skóre: 22 | blog: BluPix | Horní Smrčné
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Má testovací mašina s defaultním debianem, Athlon XP 1700+, 1GB RAM

Linux Mrakoplas 2.6.18-4-k7 #1 SMP Wed Apr 18 10:37:40 UTC 2007 i686 GNU/Linux
1.-O0
2.-O2 -march=athlon-xp -pipe -fomit-frame-pointer -msse -mmmx -m3dnow 
-ffast-math -fprefetch-loop-arrays -finline-limit=600 -ftracer
3.-Os -march=athlon-xp -pipe
4.-O3 -march=athlon-xp -pipe
                                          1       2       3       4
Standard memcpy() test                    220.70  163.90  169.10  164.10
Offset-driven copy test (bytes)           964.70  319.50  288.20  266.60
Offset-driven copy test (ints)            288.20  127.00  174.90  185.40
Offset-driven copy test ('long long's)    218.90  145.70  144.00  145.70
Pointer-driven copy test (bytes)          915.90  286.50  296.90  266.50
Pointer-driven copy test (ints)           274.60  133.60  176.40  165.60
Pointer-driven copy test ('long long's)   217.70  145.20  163.90  145.00
Special 'modulo' copy test (bytes)        868.50  242.10  226.70  227.40
Special 'modulo' copy test (ints)         258.00  163.60  164.40  156.60
Special 'modulo' copy test ('long long's) 218.70  144.30  143.00  144.30
Spock: "Logic, logic, logic. Logic is the beginning of wisdom, not the end.
28.5.2007 22:20 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()

Ale tohle je 32-bitový stroj, že jo? Takže to s tím memcpy() je fakt záhada. Připadá mi, jako by tvůrci knihoven věnovali víc pozornosti Intelu na úkor AMD. Ani v jednom případě není memcpy() vítězem. To je do očí bijící rozdíl. V procesorech AMD se skrývá nějaký tajemný nevyužitý potenciál. :-D

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
29.5.2007 02:36 Michal Kubeček | skóre: 71 | Luštěnice
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Asi bude záležet na verzi gcc, u mne (gcc 4.1.2, CXXFLAGS='-march=k8 -m64 -O3 -fomit-frame-pointer') je na Athlon64 3500+ memcpy() zřetelně nejrychlejší (kolem 40), pak následují všechny verze používající typ long long (77-78).
29.5.2007 12:50 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()

Nejspíš má tedy problém jen některá verze na některých strojích. Nechtělo se mi věřit, že by byla opravdu memcpy() obecně pro AMD pomalá. Už přece musely proběhnout tisíce benchmarků, mnohem podrobnějších a přesnějších než ten můj. (A kdyby se na něco takového přišlo, bylo by to už před lety v knihovnách opraveno.) I tak jsou výsledky zajímavé. :-)

ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 22:01 Andrej | skóre: 47 | blog: Republic of Mordor | Zürich
Rozbalit Rozbalit vše Sekec, mazec, BUM!

Hádejte, kdy ten můj benchmark hodí segmentation fault! :-)

Stane se to tehdy, když uděláte na Intelu spccpy< long double >(). Napřed se mi to zdálo podivné, ale počítač má vždycky pravdu:

Jest totiž sizeof( long double ) == 12. (Pentium M, Linux, GCC) Dále jest MEMSIZE / 12 == 8333333, což zjevně není násobkem osmi. Proto v tom while cyklu podteče proměnná bytes do velkých čísel. Je totiž bezznaménková. :-(

Jsou dvě možnosti řešení:

  • Nastavit si MEMSIZE = 120000000u. Pak bude MEMSIZE / 12 násobkem 8.

  • Nikdy nepoužívat unsigned proměnnou jako řídící proměnnou cyklu. Tuto poučku jsem stokrát slyšel, stokrát porušil a stokrát jsem si nabil nos.

Blogpost raději ponechávám v původní podobě, protože většina lidí nebude chtít testovat dvanáctibytové datové typy. :-) Navíc bych tím znehodnotil výsledky, které mi tu už někteří z vás ochotně napsali.

Testoval jsem důkladně rychlost kopírování v plovoucí rádové čárce. Zdá se mi, že na procesorech Intel v tom vůbec není rozdíl. Jediné, co hraje roli, je velikost proměnné. Procesory Intel totiž mají univerzální registry pro různé typy dat. Možná by ale na jiném procesoru byla situace jiná. S upraveným MEMSIZE mám takovouhle funkci main():

int main( void ) {
	struct memcpy_test	tests[ 19 ];

	tests[ 0 ].test_name = "Standard memcpy() test";
	tests[ 0 ].memcpy_function = std_memcpy;
	tests[ 1 ].test_name = "Offset-driven copy test (bytes)";
	tests[ 1 ].memcpy_function = func_type( pluscpy, char );
	tests[ 2 ].test_name = "Offset-driven copy test (ints)";
	tests[ 2 ].memcpy_function = func_type( pluscpy, int );
	tests[ 3 ].test_name = "Offset-driven copy test ('long long's)";
	tests[ 3 ].memcpy_function = func_type( pluscpy, long long );
	tests[ 4 ].test_name = "Pointer-driven copy test (bytes)";
	tests[ 4 ].memcpy_function = func_type( endcpy, char );
	tests[ 5 ].test_name = "Pointer-driven copy test (ints)";
	tests[ 5 ].memcpy_function = func_type( endcpy, int );
	tests[ 6 ].test_name = "Pointer-driven copy test ('long long's)";
	tests[ 6 ].memcpy_function = func_type( endcpy, long long );
	tests[ 7 ].test_name = "Special 'modulo' copy test (bytes)";
	tests[ 7 ].memcpy_function = func_type( spccpy, char );
	tests[ 8 ].test_name = "Special 'modulo' copy test (ints)";
	tests[ 8 ].memcpy_function = func_type( spccpy, int );
	tests[ 9 ].test_name = "Special 'modulo' copy test ('long long's)";
	tests[ 9 ].memcpy_function = func_type( spccpy, long long );

	tests[ 10 ].test_name = "Offset-driven copy test (floats)";
	tests[ 10 ].memcpy_function = func_type( pluscpy, float );
	tests[ 11 ].test_name = "Offset-driven copy test (doubles)";
	tests[ 11 ].memcpy_function = func_type( pluscpy, double );
	tests[ 12 ].test_name = "Offset-driven copy test ('long double's)";
	tests[ 12 ].memcpy_function = func_type( pluscpy, long double );
	tests[ 13 ].test_name = "Pointer-driven copy test (floats)";
	tests[ 13 ].memcpy_function = func_type( endcpy, float );
	tests[ 14 ].test_name = "Pointer-driven copy test (doubles)";
	tests[ 14 ].memcpy_function = func_type( endcpy, double );
	tests[ 15 ].test_name = "Pointer-driven copy test ('long double's)";
	tests[ 15 ].memcpy_function = func_type( endcpy, long double );
	tests[ 16 ].test_name = "Special 'modulo' copy test (floats)";
	tests[ 16 ].memcpy_function = func_type( spccpy, float );
	tests[ 17 ].test_name = "Special 'modulo' copy test (doubles)";
	tests[ 17 ].memcpy_function = func_type( spccpy, double );
	tests[ 18 ].test_name = "Special 'modulo' copy test ('long doubles's)";
	tests[ 18 ].memcpy_function = func_type( spccpy, long double );
	
	if ( !test_alloc( MEMSIZE ) ) { return 1; };
	test_run( tests, 19, 10 );
	test_free();
	return 0;
}
ǑǦŹǓǕǙǞǺǨȞȬḔḦḰḾṊṎṸẄẌỖ
28.5.2007 23:06 Petr Zelenka | skóre: 24 | Semice/Stuttgart (Sindelfingen)
Rozbalit Rozbalit vše Re: Sekec, mazec, BUM!

Nemyslím si, že požívat unsigned proměnnou v řídící části cyklu je hřích. Naopak, ve chvíli, kdy přičítáte, my přijde jako velice vhodné přičítat do unsigned. Při odčítání je to ale jiná káva.

A teď si uvědomte, jaký je vztah mezi krychlí a motýlem.
29.5.2007 13:07 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše AMD Duron
Linux album 2.6.21-gentoo-r2 #1 PREEMPT Fri May 25 11:39:18 CEST 2007 i686 AMD
Duron(tm) processor AuthenticAMD GNU/Linux

gcc (GCC) 4.1.2 (Gentoo 4.1.2)

1. g++ -Wall -O0
2. g++ -Wall -march=athlon-tbird -O3 -pipe -fomit-frame-pointer

                                           1.       2.
Standard memcpy() test                      660.30  386.80
Offset-driven copy test (bytes)            1882.60  736.00
Offset-driven copy test (ints)              688.90  377.30
Offset-driven copy test ('long long's)      671.00  352.60
Pointer-driven copy test (bytes)           1849.40  734.00
Pointer-driven copy test (ints)             795.90  378.70
Pointer-driven copy test ('long long's)     637.10  365.00
Special 'modulo' copy test (bytes)         1790.80  698.80
Special 'modulo' copy test (ints)           795.10  366.40
Special 'modulo' copy test ('long long's)   667.40  363.50
Není to tak zřetelné, ale memcpy také propadá.
29.5.2007 13:43 peter_h | blog: need4speed
Rozbalit Rozbalit vše Re: Jednoduchý benchmark pro memcpy()
Super test! Len by som chcel dodat k memcpy, ze pokial to nie je intrinsic (alebo ako sa to pise) alebo skompilovane priamo zo zdrojakov tak by bolo dobre vsetky ostatne testy porovnavat s rovnakymi prepinacmi kompilatora ako bola skompilovana libc. Aj tak je ale asi memcpy optibalizovane v asm (na pouzitie sse).

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.