Diskuze: Soutěž v programování :)

Tvůrce

Zobrazeno 42 zpráv z 92.
Sakra, chlape, tebe je na ten Gamemaker skoda
Game Maker by si zasloužil víc takových a nebyl by to pak
takový ušmudlánek.
Zkus sem schválně ještě nějaký další násobky miliónu, kolik tvůj
sort zvládne maximálně a jaký budou časy a porovnal bych to s ostatníma
řešeníma
10M ... 111.45s
20M ... 222.82s
Při vysokých počtech asi narazím na hranice GM pro práci
s datovými strukturami a musel bych přepsat další vestavěné funkce.
Uvidíme, zkusím pak rozjet 500M, jestli se to nepodělá.
500 M asi ne, to nenacpes do pameti, pokud je vysledek z GM 32bit.
Ja v 32bit C++ muzu radit max tak 480M.
Tak mě napadá otázka. Smí se řazení spojit s genrováním? Tzn, že se vygeneruje slovo a hned se zařadí na správný místo?
Škoda, to by otevřelo dost nových možností ...třeba použití mediánu
jako pivot u quick sortu.
Nebo třeba rovnou pole vygenerovat seřazené
Je tam podmínka že znaky a délka mají bejt náhodný, takže ho těžko
vygenreueš už seřazený
Tak jsem se do toho dneska pustil s jiným algoritmem, a dostal jsem se u 1M
na 500 mls, ale na ta vaše čísla se asi nedostanu.
Tak jsem se u řazení dostal na následující čísla.
100 000 : 8 ms
1 000 000 : 50 - 55 ms
10 000 000 : 460 - 500 ms
100 000 000 : cca 4,8 s (ale generování trvá přes půl minuty)
Nic rychlejšího už mě nenapadá.
U mě generování taky trvá dýl než řazení
100M mám za 1,8 s
Můžeš mi zkusit poslat exáč, zkusím to na svém procesoru, ať jsou stejné podmínky.
Metodu evidentně používáme stejnou, takže rozdíl už je asi jen v implementaci.
Poslal sem ti to i se zdrojákem. Myslim že kód pochopíš snadno.
Tvůj alg. na mém počítači (v závorce časy mého alg.)
1 000 000 33ms (27ms)
10 000 000 290ms (202ms)
100 000 000 2850ms (1890ms)
Už si nepamatuju, jestli jdeš na sraz, pokud ano, tak se připomeň, máš
u mě drink
Na sraz nejdu, ale celkem rád bych viděl tvuj algoritmus, můžeš mi ho
poslat na mail?
Dík... moc se v tom nevyznam Pochopil sem žes použil stejnej řadící algoritmus jako já, ale
tvoje implementace je o dost složitější, asi bych hodně dlouho koumal jak
to funguje
Jinak musim uznat že to zadání je dost dobře vymyšlený.
Díky, po pátku to tu zveřejním a trochu popíšu, jen asi budu muset
vyhodit to goto, jinak mě Kit zabije .
Taky bych sem moh pak hodit to svoje, sice to neni tak rychlý, ale je to
kratší a jednodušší.
Bylo tu řečeno je multithreading je povolen, takže sem to ještě poněkud
zrychlil, počítam že tvuj procesor má alespoň 2 jádra. Pošlu ti to na
mail
Teď jsem už v Praze, tady mám k dispozici jednojádrový notebook a
dvoujádrový core i3 na 3 GHz,
10M té vícejádrové verze tu (na tom i3) trvalo 175ms (moje verze tu trvá
145ms - už se docela blížíš ), nemáš doma 4jádro, že by jsi to přepsal pro 4 jádra a zkusil
poměřit to u tebe?
Pár dalších tipů na optimalizaci:
Místo short intů můžeš použít zkusit použít (unsigned) char, i když to
asi na výkon vliv mít moc nebude.
Znaky bych neukládal jako pole polí znaků, ale jen jako pole znaků (i když
to je vnitřně vlastně fuk, stejně to pak bereš jako jedno velký pole).
Jedno slovo bych ukládal jen jako 4 znaky - tj. pokud je slovo dlouhé 4
znaky, tak na konci nemá nulu, když o tom víš předem, tak proč to
nevyužít
Memory alignment někdy dokáže taky trochu vylepšit rychlost a hlavně ti
umožní nějaké další optimalizace, jako třeba vymazat všechny 4 znaky na
nulu v podstatě jednou instrukcí.
Ta změna na char možná lehce pomohla, ale nijak zvlášť. Zkrácení na 4 znaky nepomohlo vůbec a ty řetězce nikde nenuluju, rovnou je přepisuju...
Ještě mě napadla jedna optimalizace, mělo by to ale jeden problém, ve výstupnim poli by všechny stejný řetězce měly stejnou adresu, tzn pokud by se jeden změnil, změnily by se všechny stejný. Navíc by to na rychlosti bylo znát jenom u velkých čísel, kde by bylo hodně řetězců stejných.
Edit 19:15 :
Navíc by to nešlo bez memory leaků. Správná dealokace paměti by hrozně
moc snížila rychlost...
BTW přístup do pole counts nemáš thread-safe, když v jednu chvíli obě vlákna (při tom inkrementování) přistoupěj na stejný index, tak se taky může stát, že se počet zvýší celkově jen o jedničku.
A ještě jednu docela velkou optimalizaci tam můžeš udělat.
Při výpisu si můžeš tu hodnotu cacheovat.
Když třeba se řetězec s id 123456 opakoval desetkrát, tak ty tam desetkrát
ten řetězec vypočítáš z toho čísla. Přitom by stačilo si ho
předvypočítat jednou a pak ho už jen použít.
EDIT: a nejlepší na tom je, že si ten řetězec můžeš uložit jako jeden int a ten tam vlepovat jedním přiřazením (mám to tak ve svém kódu).
Na stejnej index se nikdy dostat nemůžou, kdyby ano, tak by se tam dostaly
pokaždý a naopak by to tu hodnotu započítalo 2x. Každý vlákno má svojí
půlku kterou projíždí, do tý druhý půlky se nikdy nedostane.
To s tim počítánim z jednoho čísla by právě šlo obejít tak, že bych
jenom kopíroval pointer, pak mi tam ale zůstane halda nedealokovaný
paměti.
Ta metoda s int mě nenapadla...
Číst ze stejnýho pole nemůžou, každý má svoji půlku, právěže ten problém je ale inkrementace hodnot v poli countArray, kde se to stát může.
buďto můžeš využít něčeho takovéhohle: http://msdn.microsoft.com/…s.85%29.aspx
(ale netuším, jaký to má vliv na rychlost)
Nebo třeba udělat si pro každé vlákno vlastní countArray a pak je nakonec sečíst (to zase můžeš udělat vícevláknově - jedno vlákno třeba horní půlku, druhé dolní)
Já teda nevím, ale v pekle to začalo. Teď už to jde do nebes
Ty pole se nemusí sčítat, stačí ve výslednym přepočtu vždy sečíst
hodnotu na stejnym indexu v obou polích. ...což už vlastně dělá každý
vlákno zvlášť.
Ano, takhle jsem to sčítání polí myslel
Poslal sem ti na mail poslední verzi, víc zesložiťovat už to nebudu, mam
na práci i jiný věci
...po pátku sem hodim tu původní verzi, tu co běžela na jednom
vlákně.
Trva to porad stejne dlouho, mozna bys musel to pole znaku zarovnavat na
ctverice misto na petice
Já sem tu velikost slov vrátil zpátky jak to bylo, rozdíl v rychlosti v
tom nebyl a takhle ty slova můžu aspoň normálně vypsat, když mají na
konci nulovej znak, nemusim je vypisovat znak po znaku... Změnil sem jenom ty
short int na char, ošetřil ty vlákna a udělal kopírování řetězců přes
int podle prvního, což rychlost trochu zvedlo, ale to sčítání polí kvůli
vláknům jí zase srazilo.
Ahoj, tak jsem tu (konečně) s výsledky.
Podmínky jsem upravil tak, aby se dal i na řazení řetězců použít counting sort, který má lineární složitost, takže hlavně u velkých množství slov je neskutečně rychlý. Pro svoje řešení jsem kvůli rychlosti zvolil C++.
Nejblíže se dostal Luckin, jehož (taktéž jednovláknová) C++ verze counting sortu u 10 000 000 slov trvala 290ms (moje 170ms).
Speciální ocenění získává TomBen, který, ač využívá GameMaker, také přišel na to, že se dá použít counting sort a sesortování 10 M slov mu trvalo 111 sekund, což se asi bude blížit limitům gamemakeru.
Tady je zdroják mé verze, kód je mírně komentován, kdyby jste měli
nějaký dotaz nebo jste tam našli nějakou chybu, tak to tu prosím napište
do komentářů.
http://www.itnetwork.cz/dev-lighter/65
Díky všem za účast, zapojilo se vás nakonec docela dost.
Myslíte, že byl rozsah tak akorát nebo byste dali na příště přednost
něčemu většímu/menšímu?.
Tady je moje verze jak jsem slíbil
Jedno vlákno: http://www.itnetwork.cz/dev-lighter/66
Dvě vlákna: http://www.itnetwork.cz/dev-lighter/67
Tak to mam skoro stejne jako ty. Jen sem nepouzil lowendove konstrukce a mej
jse problem u counting sortu s prevedenim cisla zpatky na slova(znaky)
Urcite bych ocenil dalsi soutez a muze to byt klide neco vetsiho.
Zobrazeno 42 zpráv z 92.