Kuna arvutuslik füüsik, ma olen tihti töötavad programmid, mis koosnevad paljudest nested for silmuseid . Praegu minu äärepoolseimate loop tsükleid miljonite andmepunkti ja erinevate sisemine silmad uurida kümneid tuhandeid parameetreid. Ma olen alati Juhtiv koos seaded sisemine silmad viisil, mis tekitab läbijooksuaeg varieeruda vahemikus 10 sekundit ja 10 nädalat.
Tüütult, see ei ole alati kerge ennustada, kui kaua programm kestab pärast iga rida muudatusi. Ka minu koodi aeg-ajalt vigu, mille tõttu on hanguda lõputult. Kui programm on oodata läbijooksuaeg mõõdetakse nädalat, see on rahustav näha regulaarseid aruandeid. Muidu ma muretsema, et programm on vaikselt alla kukkus.
Alguses ma lihtsalt slapped printida avalduse arvesse äärepoolseimate jaoks ahela, kapslis , kui-siis avalduse, mis ainult aktiveeritud kord iga 1000 silmuseid. Prindi avaldus kasutatud möödunud aeg algust silmuse ja edusammude hindamiseks aega jäänud. See tundus natuke selline (pluss mõned tüüpi valu ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | ( NULL ) ; //Grab starting time. start_time = aeg (NULL); / / Haara algusaega. i = 0 ; i < i_end ; i ++ ) { for (i = 0; i <i_end; i + +) ( i + 1 ) % 1000 == 0 ) { //Only print every 1000 loops. if ((i + 1)% 1000 == 0) (/ / Ainult printimine 1000 silmuseid. ( NULL ) ; //Grab current time. current_time = aeg (NULL); / / Haara praegust aega. start_time ; kestuseta = current_time - start_time; / / Koguaja lõpetamist võib saada / / Jagades kestuseta poolt fraktsioon juba teinud. / / Pärast lahutatakse kestuseta jääv aeg / / Jääb (sekundites, mis on tihti segane). ( i + 1 ) / ( i_end + 1 ) - timespan ; time_remaining = kestuseta / (i + 1) / (i_end + 1) - kestuseta; ( i + 1 ) / i_end * 100 << "% finished, " kohus <<(i + 1) / i_end * 100 <<"% valmistoote" "seconds remaining." << endl ; <<Time_remaining <<sekundit jäänud. "<<Endl; ) j = 0 ; j < j_end ; j ++ ) { jaoks (j = 0; j <j_end; j + +) ( / / Kas palju kraami. ) ) |
See piisas kuni ma muutnud koos seaded sisemine silmad viisil, mis kasvas läbijooksuaeg dramaatiliselt. Esimese teate leidis tundi ilmuma, mida ma pean lubamatult aeglaseks. Siis ma proovisin teha print avaldus aktiveerib iga 10 silmuseid kiirendada teateid, kui läbijooksuaeg on väga pikk, kuid täis logifail koos MB prindi avaldused ning pidurdanud programmi. On selgunud, et kiire hacks ei kavatse nõuda palju pidevat hooldust. Mul oli vaja teatamise süsteem, mis võiks automaatselt kohaneda lühikeses ja pikas perspektiivis korda.
Kutsun minu lahendus "Automaatne Teated". Viimane versioon on v1.2, mida saab alla laadida siit .
Omadused:
- Ajal kuni esimese teate tundub võimalik kontrollida lahus muud teated, ja see vaikimisi 10 sekundit.
- Aja vahel kõik hilisemad teated poolt kontrollitava muutuja, mis määrab eesmärgi vahele teated. Tegelik järel on 30% sellest eesmärgist (5 minutiline vaikimisi).
- Minimaalne arv (vaikimisi 4) teateid trükitakse teatama (). See ainult aktiveerib kui prognoositud perspektiivis on lühem kui valitud intervalli teated.
- Tähtaja lõpuni on trükitud inimloetavas vormi abil, kasutades seconds_to_string () funktsiooni. Aeg on aru aastat, nädalate, päevade, tunnid, minutid, sekundid. Mitte rohkem kui 2 ühikut trükitakse iga avaldust vähendada segadusega (kuigi see väärtus on kohandatav).
- Prindi avaldust aruannete möödunud aeg lõpus silmus, nii eeldatav aeg ülejäänud seda saab otsustada peale kaua silmus tegelikult võttis.
- Välimine ring võib alata igal (positiivne! - Vajadust määrata see!) Indeks, mitte ainult 0, eespool toodud näites.
- Enamik teate seadistatakse kõrgus iga silmus, nii mitu silmuseid saab seadistada erinevalt (vt custom_example.cpp).
- See on ilmselt hea mõte panna kood teatamise funktsiooni, mis salvestab andmeid kettale nii, et kui arvuti jookseb või võimu kustub, taotluse võib uuesti alustada viimase teate punkti. Muutuja notification.partial_saves_enabled on mõeldud omakorda selle kirjutamata koodi, kuid teil on samuti vaja läbida uut argumenti teatama () funktsiooni, mis sisaldavad andmed, mida soovite kirjutada kettale.
Nõuded:
- Mõeldud kasutamiseks C + + programmid, katsetatakse g + + kompilaator, et kaasas Ubuntu 8.10 64-bit .
- Teie äärepoolseimate loop tuleb tsükli jooksul palju indeksite (kümneid või rohkem). Loop võib alustada igal indeks soovite, kuid see peab suurendama 1. Iga ahela.
- Nõuab iostream, iomanip ja vektori raamatukogud (saadaval Ubuntu vaikimisi).
Programm on jagatud 3 faili: common_declarations.hpp sisaldab andmetüüp mõisted ja funktsioon on deklaratsioonid, common_functions.cpp on funktsiooni mõisted teatama () ja sec2human () samas example.cpp on ainult näide silmus, mis kasutab automatiseeritud Teadaanded.
Selline jaotus ei ole vajalik, kuid ma olen leidnud on see hea viis korraldada suuremaid tarkvara projekte. Sel moel kasutatakse laialdaselt funktsioone, mis on harva muutunud võib deklareeritud ja määratletud ühise faile ja koostada eraldi programme, mis lihtsalt kasutavad neid funktsioone.
Makefile kaasas Automatiseeritud Teavitused koostab kahes etapis, et illustreerida seda tehnikat. Olles lisanud palju funktsioone minu versioon common files esimene koostamise samm võtab peaaegu minut minu arvutis. See samm tekib ainult siis, kui ühine faile muuta, aga mis tähendab see on harva vaja. Teine koostamise samm, teiselt poolt, on sagedasem ja palju kiiremini.
Muide, common_declarations.hpp sisaldab rida "kasutades namespace std". Olen lugenud , et see on halb programmeerimise tava, kuid ma pole sattunud ühtegi tõsiseid tagajärgi veel ja see on mugav ei oleks vaja tüüp "std::" iga kord ma tahan kasutada "kohus".
Here's what example.cpp näeb välja selline:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | /************************************************* ******* Eesmärk: See programm kestab sätestatud Pesastatud silmad täitma kasutud arvutused mitu minutit (täpne aeg sõltub kiirus arvuti ja piirid nested silmuseid). See tähendas, et näidata teatama () funktsiooni. ************************************************** ******* Kirjutas Dumb Teadlane Esimesed kirjalikud: 2009/02/26 Viimati muudetud: 2009/03/08 ************************************************** ******/ / / Päisefail "common_declarations.hpp" kuulutab paljud / / Ülesannete konstandid ja andmetüübid. Selleks, et kasutada / / Ülesandeid deklareeritud ta, peate lingi selle programmi / / Koos objekti koodi abil tehtud common_functions.cpp. # Include "common_declarations.hpp" int main () ( / / Tunnistada loendurid ja piirid silmuseid. 0 ,i,j,i_start = 30 ,i_end = 200000 ,j_end = 200000 ; kaua temp = 0, i, j, i_start = 30, i_end = 200000, j_end = 200000 / / Initsialiseeri muutujad teatama (). notification_struct teate; / / Change see string ükskõik mida tahad. "Example loop" ; teatavakstegemisest. prefix = "Näide ahela; / / Sinu alustades indeks on tõenäoliselt erinev. i_start ; teatavakstegemisest. starting_index = i_start; / / Sinu lõpeb indeks ka tõenäoliselt erinev. i_end - notification. starting_index ; teatavakstegemisest. num_loops = i_end - teatavakstegemisest. starting_index; i = notification. starting_index ; i < i_end ; i ++ ) { for (i = teatavakstegemisest. starting_index; i <i_end; i + +) ( / / Perioodiliselt prindi aega jäänud. ; teatama (teatamise i); j = 0 ; j < j_end ; j ++ ) { jaoks (j = 0; j <j_end; j + +) ( / / Täiesti kasutu arvutamisel. ( i * j * j * j - 2 * i + 3 * j ) ; temp + = (i * j * j * j - 2 * i + 3 * j); ) / / End of sisemine ring. ) / / End of välimise silmuse. / / Pane kirja aeg, programmi lõpus. time ( NULL ) ; teatavakstegemisest. end_time = aeg (NULL); notification. end_time - notification. start_time ; teatavakstegemisest. time_total = teatavakstegemisest. end_time - teatavakstegemisest. start_time; notification. prefix << " took " kohus <<teatavakstegemisest. prefix <<"oli" notification. time_total ) << endl ; <<Seconds_to_string (notification. time_total) <<endl; / / Kui temp ei kasutata kusagil, see programm võtab / / 0 sekundit. Ma arvan, et tulemus-O2 / / Lipp märgata, et eespool tsüklid ei ole vaja. tagasi temp; ) |
Kui kestab, siis toodab toodangut mis näeb välja selline (pange tähele, et esimeses reas kuvatakse mõne sekundi jooksul, ja sellele järgnenud teated 25% peale, sest hinnanguliselt läbijooksuaeg see programm on alla default intervall):
1 2 3 4 5 6 | Näide loop on 8,20%. Aega jäänud: 1 minut ja 52 sekundit Näide loop on 33,20%. Aega jäänud: 1 minut, 20 sekundit Näide loop on 58,19%. Aega jäänud: 51 sekundit Näide loop on 83,19%. Aega jäänud: 20 sekundit Näide loop võttis 2 minutit, 1 sekund " |
Muutsin piirid silmuseid lisades 4 nulli igaüks i_end ja j_end, kuid esimest rida veel ilmunud sekunditega:
1 2 | Näide silmus kell 0.00%. Aega jäänud: 285 aastat, 10 nädalat " |
Loomulikult, ma ei oodanud, et üks lõpuni. Aga küsimus on, et ma kiiresti teadsin ma surevad vanadus sajandeid enne seda tegi. Muide, ma proovisin lisada veel mõned nulle j_end ning see tekitas esimese teate võtma irritatingly pikka aega näidata. See juhtub siis välimine ring võtab kaua aega juurdekasvu ainult üks kord. Ma pole veel kindel, kuidas ma tahan selle probleemi lahendamiseks.
Automatiseeritud Teatised on vaba tarkvara, litsenseerida all GPLv3 asemel CC litsentsi , et ülejäänud sait kasutab. Kui keegi teadete kõigist vigadest või on mingeid ettepanekuid, kuidas parandada automatiseeritud Teated, palun andke teada oma kommentaarides allpool. Ma olen ka uudishimulik näha, kuidas teised on lahendatud see probleem, sõltumata keelest ta kirjaliku sisse
Version History
v1.2 - 2009/03/08 - Lihtsustatud vaikesätted lühendada example.cpp, lisatakse custom_example.cpp.
v1.1 - 2009/02/27 - Asendatud max ja min tagant koos target_interval.
v1.0 - 2009/02/26 - Original vabastamist.
Viimane muutmine: 2. august 2009

























































Ma olen üllatunud, te ei kasutanud taimer katkestada. Nr õhuliini samas loop töötab ja täpne gaasiproovi intervalli. Lihtsalt on vaja mingil moel saada silmus muutujaid arvesse katkestada käitleja ja tulemused välja.
Kas ei kasuta seda, sest ma polnud kunagi kuulnud seda varem. Aitäh, teen asja.
"Tootmiseks" versioon sellest funktsioon aktsepteerib struktuur mitme GB andmeid ja autosaves see kettale. Ma mõtlesin, et kui taimer katkestada võiks saata, et palju andmeid läbipaistev? St kogu struktuur tuleb saata viite ühe argumendi tegemata kohalike andmete koopia (see vaevalt sobib mälu juba.)
Samuti funktsioon tuleb kutsuda, et täpsed kohapeal kood, ei sees sisemine ring, muidu autosave funktsioon ei toimi korrektselt. Kui kõik see on võimalik taimerit peatada, keegi palun punkt mul mõned näiteks koodi.
(Ed. Märkus: See kommentaar oli algselt postitatud siia .)
Miks? See tähendab lihtsalt pean avatud rohkem faile, kui ma tahan teha ulatuslikke hooldus programmi kohta.
Kompileerimine on kindlasti kiiremini kui sa muuta ainult 1-100 samamoodi suurusega faile, kuid ma olen otsustanud luua kaks peamine allikas failid: esimene on harva toimetatud ja suur (30k rida), samas kui teine on muutnud kümneid kordi päevas ja on ainult 1k liinidel. Makefile koostab suur fail objekti kood, mis on siis seotud objekti kood väike fail. Suur fail on seejärel alles koostatakse, kui vaadata kuupäeva suur allikas fail on uuem kui suur objekt faili. Isegi kompileerida korda suur fail on ainult ~ 10 sekundit netbook kui optimeerimine on keelatud ja see ei ole selge, et minu kompileerida korda kasvab kiiremini kui CPU kiiruste tahet. (Eriti kui paralleelselt g + + kunagi saab korralikud.)
Ma arvan, et võib öelda, et kood killustatust aitab jõustada "paar võrkude vaheliste ülesannete" põhimõtet. (Või mis iganes see on ametlikult kutsunud-arusaam, et ülesannete hulka peaks suhelda ainult paar hästi määratletud viisil.) Käesolev ideaalne teoreetiliselt on atraktiivne, kuid tundub tüütu rakendada lubamata aeg-ajalt erandeid. Ma ei taha muutuda kasulik suunis arvesse jäiga õiguse, mis ilmselt lihtsalt aeglane mind maha.
Olen ka kirjutada koodi ise, nii seotud põhjused programmeerimine meeskonnad ei ole tegelikult oluline. Hea versioonikontrolli süsteemi nagu Hägune tuleks vähendada neid küsimusi nagunii.
Kas on olemas reaalne (st tootlikkuse, mastaapsuse) põhjustel loobuda selline lähenemine ning alustada pannes uued funktsioonid eraldi failides? Ma ei ole professionaalse programmeerija, nii et ma võis jääda midagi sellist, arvutiteadus PhD kaaluks selge ja kaalukas ...
Kuna te litsentsi koodi all GPL (nii et põhimõtteliselt sa teretulnud või vähemalt ei pahanda teistega õppida ja jagada oma koodi) ning seejärel koodi juhitavuse on tore on, mida saab saavutada moodulitest .
Kõige tähtsam on meeles pidada, jagada oma koodi järgi, mida ta teeb (loogiline eraldamine). Kui aus olla ma ei ole tutvunud oma koodi nii võibolla ei kohaldata käesolevas asjas (võibolla üks tõeliselt suur fail on põhjendatud).
Sanottuani lõpus päeval puuduvad jäigad seadused, just suuniste põhjal loodud kogemusi ja palju vigu:)
Suurepärane võrra. Täname artikkel.