{"id":97160,"date":"2020-10-16T14:42:31","date_gmt":"2020-10-16T12:42:31","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa"},"modified":"2020-10-16T14:42:31","modified_gmt":"2020-10-16T12:42:31","slug":"optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa","title":{"rendered":"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Mis m\u00f5jutab C++ programmidest s\u00f5ltuvat t\u00f6\u00f6kiirus ja kuidas saavutada seda k\u00f5rge kooditaseme juures? CatBoosti raamatukogu juhtiv arendaja Jevgeni Petrov vastas nendele k\u00fcsimustele CatBoosti x86_64 arenduse n\u00e4idete ja illustreerimise kaudu.<\/p>\n<p>                        <b class=\"spoiler_title\">Ettekande video<\/b><br \/>\n                        <center><div class=\"youtube-placeholder\" data-id=\"QY6aLjvKRNM\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/QY6aLjvKRNM\/hqdefault.jpg\" alt=\"Vaata videot\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><br \/>\n                    <br \/>\n\u2014 Tere k\u00f5igile. Tegelema optimeerimisega CatBoosti masina\u00f5ppe raamatukogus CPU jaoks. Enamik meie raamatukogust on kirjutatud C++ keeles. T\u00e4na r\u00e4\u00e4gin lihtsatest viisidest, kuidas saavutame kiirus.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/1fb6e12279d48031f443fbf7260d7449.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nArvutuste kiirus koosneb kahest osast. Esimene osa on algoritm. Kui me teeme valiku algoritmi osas vale, siis ei saa me seda hiljem kiiresti t\u00f6\u00f6le panna. Teine osa on see, kui h\u00e4sti on meie algoritm optimeeritud arvutis\u00fcsteemile, mis meil on, koos selle j\u00f5udluse ja l\u00e4bilaskev\u00f5imega.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/d6a7e874ce6dfa1d6260dd109dfcbeb1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAndmevahetuse ja arvutuste eraldi arvestamine tuleneb nende kiirusvahe suurest erinevusest. Kui v\u00f5tta m\u00e4lu kiirus jalak\u00e4ija kiirusena, siis arvutuste kiirus on umbes reisilennuki kruiisikiirus. <\/p>\n<p>Selle erinevuse tasandamiseks on arhitektuuris mitmeid vahem\u00e4lu tasemeid. Kiireim ja v\u00e4ikseim on L1-vahem\u00e4lu. Seej\u00e4rel on suurem ja aeglasem teise taseme vahem\u00e4lu. Ja on ka t\u00e4ielikult suur vahem\u00e4lu, mis v\u00f5ib ulatuda k\u00fcmnete megabaitideni, kolmanda taseme vahem\u00e4lu, kuid see on k\u00f5ige aeglasem. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/4f81ec51ea19380e805f87a978dd9aec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKuna andmeedastuskiirus varieerub, jaguneb arvutuslik kood kaheks klassiks. \u00dcks klass on piiratud l\u00e4bilaskev\u00f5imega, st andmeedastuskiirus. Teine klass on piiratud protsessori t\u00f6\u00f6kiirusest. Piir nende vahel seab, s\u00f5ltuvalt operatsioonide arvust, mis viiakse l\u00e4bi \u00fche andmabytega. See on tavaliselt konkreetse koodi jaoks konstant. <\/p>\n<p>Enamik raskest arvutuslikust koodist on ammu kirjutatud, v\u00e4ga h\u00e4sti optimeeritud ning olemas on suur hulk raamatukogusid, seega on m\u00f5istlik, kui n\u00e4ete oma koodis raskesti arvutusi, otsida raamatukogu, mis v\u00f5iks need teie eest teha. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/f9161a14015ef7bdb49ce53c0a9cbf40.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKuna allesj\u00e4\u00e4nud kompilaatorid ei tarvitse k\u00f5ike, sest nende arendamiseks kulutatakse v\u00e4ga piiratud protsent ressursse. Millised neist on t\u00e4na enam-v\u00e4hem aktiivsed, st toetavad standardeid ja p\u00fc\u00fcavad nende j\u00e4lgimisega tegeleda? See on frontend EDG, mida kasutatakse erinevates variatsioonides, n\u00e4iteks Intel'i kompilaator; LLVM; GNU ja Microsofti frontend.<\/p>\n<p>Kuna neid on v\u00e4he, toetavad kompilaatorid vaid sagedusmustrid juhtimise ja andmete s\u00f5ltuvuse osas. Kui vaatame juhitavust, siis need on lineaarsed l\u00f5igud ja lihtsad ts\u00fcklid, st soovituste j\u00e4rjestus ja kordamine. Sagedusandmete s\u00f5ltuvusi saavad nad tuvastada v\u00e4hendamise teel, kui me n\u00e4iteks liidame palju elemente \u00fcheks, kokkuv\u00f5tteks ja teeme elemendi-p\u00f5hiseid toiminguid \u00fche v\u00f5i mitme massiiviga. <\/p>\n<p>Mis j\u00e4\u00e4b arendajatele? Seda v\u00f5ib tinglikult jagada neljaks osaks. Esimene on rakenduse arhitektuur, kompilaatorid lihtsalt ei suuda seda meie eest v\u00e4lja m\u00f5elda. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/00d24ff76dc6ca1e6954bb0de4f29da2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nParalleelisus on ka kompilaatorite jaoks keeruline teema. M\u00e4luga t\u00f6\u00f6tamine on t\u00f5eliselt keeruline: tuleb arvesse v\u00f5tta nii arhitektuuri kui ka paralleelisust ning k\u00f5ike koos. Peale selle ei oska kompilaatorid \u00f5igesti hinnata optimeerimise kvaliteeti, kui kiireks kood muutub. Selle otsuse peame langetama meie, arendajad \u2014 kas optimeerida veel v\u00f5i l\u00f5petada. <\/p>\n<p>Arhitektuuri osas vaatame \u00fcle kulude amorteerimise, virtuaalsed kutsed, millele arhitektuur paljuski toetub. <\/p>\n<p>Paralleelisuse j\u00e4tame k\u00f5rvale. M\u00e4lukasutuse osas: see on ka mingis m\u00f5ttes amorteerimine ja andmetega \u00f5igesti t\u00f6\u00f6tamine, nende \u00f5ige paigutamine m\u00e4llu. T\u00f5hususe hindamise osas r\u00e4\u00e4gime profiilimisest ja sellest, kuidas leida koodis kitsaskohti. <\/p>\n<p>Liideste ja abstraktsete andmet\u00fc\u00fcpide kasutamine on \u00fcks peamisi projekteerimismeetodeid. Vaatame sarnast arvutuslikku koodi masin\u00f5ppest. See on tingimuslik kood, mis v\u00e4rskendab prognoosi gradientmeetodi kaudu. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/e404b354ec13dab3cc7c5025bbbdb0df.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui vaadata veidi sisse ja p\u00fc\u00fcda m\u00f5ista, mis seal toimub, siis meil on IDerCalcer liides, et arvutada kaotusfunktsiooni derivatiive ja funktsioon, mis nihutab prognoosi (meie ennustust) vastavalt kaotusfunktsiooni gradientidele. <\/p>\n<p>Paremal slaidil n\u00e4ete, mida see t\u00e4hendab kahem\u00f5\u00f5tmelises juhtumis. Masin\u00f5ppes ei ole prognoosi suurus kaks v\u00f5i kolm, vaid miljoneid, k\u00fcmneid miljoneid elemente. Vaatame, kui hea see kood on 10 miljoni elemendi vektori jaoks. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/372ba1ab08a2c13081b581d98b7cc96a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nV\u00f5tame sihtfunktsiooniks keskmise ruutspoondi ja m\u00f5\u00f5dame, kui kiiresti see prognoosi nihutab. Selle sihtfunktsiooni derivaat on slaidil. Ajavahemik fikseeritud tingimustes, mis j\u00e4\u00e4b edaspidi muutumatuks, on 40 ms. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/3e0e519797a990e181abf7589c51064b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nProovime aru saada, mis siin ikkagi valesti on. Esimene asi, mis silma torkab, on virtuaalsed kutsed. Profilatsiooni vaadates on n\u00e4ha, et s\u00f5ltuvalt parameetrite arvust on see umbes viis kuni k\u00fcmme k\u00e4sku. Ja kui, nagu meie puhul, tuletamise arvutamine on vaid kaks aritmeetilist tehet, siis v\u00f5ib see kergesti osutuda m\u00e4rkimisv\u00e4\u00e4rseks \u00fclej\u00e4\u00e4kideks. Suure objekti korral tuletiste arvutamisel on see okei. L\u00fchikese objekti puhul, mis tuletab \u2014 \u00f6eldes, isegi mitte 500 k\u00e4sku, vaid 20, 50 v\u00f5i isegi v\u00e4hem, \u2014 on see juba m\u00e4rkimisv\u00e4\u00e4rne protsent ajast. Mida siis teha? Proovime virtuaalse funktsiooni kutsumise amortiseerida, muutes liidese. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/e10fd475fffa11580585766a517271dd.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAlguses arvutasime tuletised punkt-punkt j\u00e4rgi, iga vektori elemendi kohta eraldi. Liigume elementide t\u00f6\u00f6tlemisest vektorite t\u00f6\u00f6tlemisele. Vaatame standardset C++ malli, mis v\u00f5imaldab t\u00f6\u00f6tada vektori vaatega. Kui teie kompilaator ei toeta viimast standardit, siis v\u00f5ite kasutada lihtsat isetehtud klassi, kus hoitakse andmete pointerit ja suurust. Kuidas kood muutub? Meil j\u00e4\u00e4b alles \u00fcks kutse, mis arvutab tuletised, ja siis peame lisama ts\u00fckli, mis tegelikult uuendab prognoosi. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/873254ef910bd51caae30bd795506a02.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLisaks sellele, et lisandub ts\u00fckkel, peame me veel kord vaatama andmeid, st teist korda lugema prognooside vektorit ja gradiente, mille just arvutasime. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/8ebba88623b2e4fb3bc6a238b592e4da.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKatsume taas samal masinal ja n\u00e4eme, et tulemus on halvenenud, midagi on valesti. Hakkame uurima, mis s\u00fcnteesis juhtus. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/0f462a1e51ba227e1a68e9b620919587.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPole m\u00f5tet kahtlustada ts\u00fcklit, kuna see on just see sagedusmuster, mille kompilaatorid tuvastavad ja h\u00e4sti optimeerivad. Andmete \u00fche elemendi operatsioone on seal v\u00e4hem kui virtuaalse kutse hind. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/b8274dce0b6fa31a8816f9d0b7f10039.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSiin on koha, kus v\u00f5iks kahtlustada probleemi, kui luuakse suur vektor ja sellele tehakse korduv l\u00e4bimine. Et m\u00f5ista, miks see on halb ja viib aeglustumiseni, peaksime ette kujutama, mis toimub m\u00e4lus, kui t\u00f6\u00f6tab kood, mida n\u00e4eme paremal slaidil. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/a5181b79eae0fe27f7c1232671972eec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui tuletatakse derivatiivide vektor, j\u00f5uab asi ts\u00fcklisse, mis nihutab prognoosi. Enne seda ts\u00fcklit j\u00e4\u00e4b kiircache'i esimese taseme, mis t\u00f6\u00f6tab protsessori sagedusel, ainult v\u00e4ga v\u00e4ike osa andmetest. Slaidil on see rohelise v\u00e4rviga valgusfooris. \u00dclej\u00e4\u00e4nud andmed t\u00f5ugatakse cache'ist v\u00e4lja m\u00e4llu ja kui ts\u00fckkel hakkab prognoose uuendama, tuleb andmed teist korda lugeda m\u00e4lust. Ja meie m\u00e4lu t\u00f6\u00f6tab, \u00fcldiselt, \u00fcsna aeglaselt, jalak\u00e4ija kiirusest. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/18d060d12eadd83bfd5fd6ed0137e913.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKui me prognoose uuendame, ei ole meil tingimata vaja lugeda k\u00f5iki derivatiive korraga. Piisab neist lugemisest suurte pakkidena, et amortiseerida virtuaalseid kutsunge. Seet\u00f5ttu on m\u00f5istlik jagada derivatiivide arvutamine ja prognoosi uuendamine v\u00e4ikesteks plokkideks ning segada neid kahte toimingut. Kuhu see viib, kui vaatame, kust andmed loetakse?<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/cab07960223695dfd7a5dc69f5eb9c34.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSee to, et me kogu aeg andmeid v\u00f5tame, ja et andmed j\u00e4\u00e4vad L1-vahem\u00e4lusse ega j\u00f5ua aeglasesse m\u00e4llu. Edasi peame aru saama, kes siis \u00fctleb meile selle ploki suuruse. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/6e11b2ebc942b7915a40ad672e71e577.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOn loogiline usaldada see \u00fclesanne diferentseerimise arvutajale, kuna ainult tema teab, kui palju vahem\u00e4lu tal on vaja. Edasi tuleb \u00fcmber kirjutada ts\u00fckkel, mis meil massiivi l\u00e4bi vaatas. Tuleb jagada see kaheks. V\u00e4line ts\u00fckkel l\u00e4heb plokkide kaupa, samal ajal kui sees kaks korda l\u00e4heme ploki elemente l\u00e4bi. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/ce433cc837bb2467b7a962983afaf0e1.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSiin on, v\u00e4line plokkide kaupa.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/9715c614081c49040f1ddc0199e6b37b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJa siin on seesmine plokkide elementide kaupa.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/935f7feac13dce945ab0110e1b86c0a7.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMe arvestame, et viimane plokk v\u00f5ib olla mittet\u00e4ielik. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/6ece5f4905697389f9f54a5ee58278e6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVaatame, mis sellest v\u00e4lja tuleb. N\u00e4eme, et me arvasime \u00f5igesti, m\u00f5istsime, mis asi on, ja \u00fcsna v\u00e4ikeste muudatuste hinnaga v\u00e4hendasime t\u00f6\u00f6tamise aega kaheksa protsendi v\u00f5rra. Kuid me saame veel rohkem teha. Tuleb veel kord kriitiliselt vaadata sellele, mis me kirjutasime. Vaadata funktsiooni, mis arvutab meile tuletisi. See tagastab meile tuletiste vektori, millele ligip\u00e4\u00e4s, ebasoodsates olukordades, on aeglane.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/906618deed32e7414340a58b172e4b20.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSiin on kaks p\u00f5hjust. Esiteks, vektori asukoht \u201evirnas\u201c. Suur osa t\u00f5en\u00e4osusest on, et see vektor luuakse ja h\u00e4vitatakse mitu korda. Teine kiiruselanguse probleem on see, et iga kord saame m\u00e4lu ilmselt uuel aadressil. See m\u00e4lu on \u201ek\u00fclm\u201c vahem\u00e4lu seisukohalt, see t\u00e4hendab, et enne selle kirjutamist peab protsessor t\u00f5en\u00e4oliselt tegema abitegevuse lugemist, et andmed vahem\u00e4lus initsialiseerida.<\/p>\n<p>Selle parandamiseks tuleb eraldamine ts\u00fcklist v\u00e4lja viia. Selleks peame veelkord liidest muutma, l\u00f5petama vektoreid tagastamise ja hakkama tuletisi m\u00e4lu salvestama, mille saame kutsuva koodi k\u00e4est. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/153daec8d998554897f0cca9cfeebfcd.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSee on standardlahendus \u2014 k\u00f5ik ressursside manipuleerimised tuleb v\u00e4lja viia kitsaskohtadest arvutuslikus koodis. Lisame CalcDer meetodile veel \u00fche parameetri, viidates vektorile, kuhu tuletised peavad sattuma. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/d04770bab1f5d6eca6322626626926bf.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKood muutub ka ilmselgelt. Tuletiste vektor saab olema \u00fcks, v\u00e4ljaspool k\u00f5iki silmusid, ja meetodile lisandub lihtsalt uus parameeter. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/432c024becd47bcbe4cb1c5d2a3ce707.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVaatame. Tundub, et v\u00f5itsime eelnevaga v\u00f5rreldes veel kuskil kaheksa protsenti, ja p\u00f5hipunktiga v\u00f5rreldes \u2014 juba 15%. <\/p>\n<p>On selge, et optimeerimine ei piirdu ainult kulude amordiga, kitsaskohad v\u00f5ivad olla ka teistsuguseid. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/97272a0a7c8358228892c81a12680b93.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKitsaskohtade otsimise illustreerimiseks vajame veel \u00fchte lihtsat katsekoodi. N\u00e4iteks v\u00f5tsin maatriksi transpositsiooni. Meil on maatriks approx ja maatriks approxByCol, kuhu peame paigutama transpositsioonitud andmed. Ja lihtne pesa kahest ts\u00fcklist. Siin pole mingeid virtuaalseid kutsungite, vektorite loomist. See on lihtsalt andmete \u00fcmberpaigutamine. Ts\u00fckkel on kompilaatorile suhteliselt mugav. <\/p>\n<p>M\u00f5\u00f5dame, kuidas see kood t\u00f6\u00f6tab piisavalt suure maatriksi ja konkreetse masinaga. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/913bf823ee0c379046b12c1634792476.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nN\u00e4iteks valisin ma 1000 rida ja 100 000 veergu. Masin on Intel server, \u00fches\u00fcdamikuline. M\u00e4lumaa on selline, see on meile oluline, sest kogu m\u00e4luga seotud t\u00f6\u00f6 ja kiirus s\u00f5ltuvad m\u00e4lut\u00f6\u00f6tamise kiirest. M\u00e4\u00e4rasime ja saime 1,4 s. Kas see on palju v\u00f5i v\u00e4he? Mida me selle ajaga \u00e4ra teeme?<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/4e190b7e096bc3fbb29596e2e332df44.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMe j\u00f5uame lugeda 800 megabaiti, see ei ole transponeeritud maatriks, vaid algne. Samuti suudame lugeda ja kirjutada 1,6 GB, see on juba transponeeritud maatriks. Protsessor sooritab abistava lugemise enne kirjutamist, et andmed vahem\u00e4lus initsialiseerida.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/e9f7930584dfa2d9d9b1fd39cf734b41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nArvutame, kui palju l\u00e4bilaskevust oleme kasulikult kasutanud. Meie koodi l\u00e4bilaskvus on 1,7 GB\/s. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/1629f44ddc3eb1be1427644543f01a0a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSee oli teoreetiline arvutus. J\u00e4rgmise sammuna v\u00f5ime kasutada profiilerit, mis on v\u00f5imeline m\u00f5\u00f5tma m\u00e4lu kasutamise kiirus. Kasutasin VTune'i. Vaatame, mida ta n\u00e4itab. Tulemuseks on sarnane number \u2014 1,8 GB. \u00dckski see ei ole halb, sest meie arvutuses ei olnud arvesse v\u00f5etud, et tuleb lugeda ridu ja veergude aadresse. Lisaks registreerib VTune ka operatsioonis\u00fcsteemi taustategevuse. Seega on meie mudel koosk\u00f5las tegelikkusega. <\/p>\n<p>Kuna 1,7 GB on palju v\u00f5i v\u00e4he, tuleb v\u00e4lja selgitada, milline on meie maksimaalne ligip\u00e4\u00e4setav l\u00e4bilaskvus. <\/p>\n<p>Selleks tuleb lugeda protsessori spetsifikatsioone. Loodus v\u00f5ib k\u00f5ik \u00fcksikasjad leida spetsiaalselt veebilehelt ark.intel.com. Kui vaatame konkreetselt meie serverit, siis n\u00e4eme, et sellel on kaheksa tuuma ning kiireim DDR3 m\u00e4lu, mida ta toetab, tagab andmete edastamise kiirusena umbes 60 GB\/s \u00fches suunas. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/c3683ad0d50e6bd67f43d6d05dfa56c8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKuid peab arvestama, et kasutame ainult \u00fchte tuuma ja meie m\u00e4lu on aeglasem, seega tuleb neid 60 GB meie tingimustes proportsionaalselt tuumade arvu ja m\u00e4lufrektsiooniga skaleerida. <\/p>\n<p>Tulemuseks on, et meie kood v\u00f5iks kasutada 5,3 GB \u00fches suunas. Kuna samaaegselt saab lugeda ja kirjutada, siis ideaaljuhul, kui me lihtsalt kopeeriksime andmeid \u00fchest kohast teise, saavutaksime 10,6. Arvestades, et meil on kaks lugemist ja \u00fcks kirjutamine, peaks olema umbes 8 GB\/s. Meie tulemus on 1,7. See t\u00e4hendab, et oleme kasutanud umbes 20%.<\/p>\n<p>Kuidas see nii kujuneb? Taas tuleb vaatama hakata arhitektuuri. Asjaolu on see, et andmed edastatakse m\u00e4lu ja vahem\u00e4lu vahel mitte suvaliste paketidena, vaid t\u00e4pselt 64 \u0431\u0430\u0439\u0442\u043e\u0432\u00e4. See on esimene m\u00f5te.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/4bebc908c2943f31eec88b4a0f87a449.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTeine kaalumise aspekt: me salvestame transponeeritud andmeid mitte j\u00e4rjest, vaid suvaliselt, kuna maatriksi read asuvad m\u00e4lus ettearvamatul viisil. <\/p>\n<p>Selgub, et enne \u00fche reaalarvu salvestamist peame lugema 64 baidi andmeid. Kui m\u00e4\u00e4rata maatriksi suurus N, siis optimaalse t\u00f6\u00f6aja (N\/5,3 + N\/10,6) asemel saame (8*N\/5,3 + N\/10,6). See on kuskil neli-viis korda rohkem, mis seletab 20% efektiivsust. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/907047ca3773cde1a839a2706acecadb.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMida sellega teha? Tuleb l\u00f5petada andmete salvestamine \u00fchiselt \u00fchte veergu ja alustada salvestamist nii palju veerge kui mahub \u00fchte vahem\u00e4luliini (64 baidi). Selleks jagame veergude ts\u00fckli vahem\u00e4luliinide ts\u00fckliks ja sisemise ts\u00fckliks vahem\u00e4luliini elementide jaoks. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/71ddfaaae3892ff1d5fe25fe58d7a89b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSiin nad on, vahem\u00e4luliinide iteratsioonid. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/4a3ec684198f0e9badf583f147eeabdb.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJa siin nad on, iteratsioonid vahem\u00e4luliinis. Siin arvame lihtsuse huvides, et andmed on joondatud vahem\u00e4luliini piirile. N\u00fc\u00fcd kontrollime VTune'i abil, mis juhtub. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/7015b6509fdb3d5c7f11866e9948c6e2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nN\u00e4eme, et saavutame ligikaudu arvutatud kaheksa gigabaiti sekundis \u2014 7,6. Kuid pole veel kindel, et k\u00f5ik need 7,6 on kasulik t\u00f6\u00f6. V\u00f5ib-olla osa neist on lisakulud. <\/p>\n<p>Kuna m\u00f5ista, kui palju kasu me saavutasime, m\u00f5\u00f5dame t\u00f6\u00f6aega p\u00e4rast optimeerimist. See on 0,5 s samal masinal. L\u00e4bivus, mis on seotud transpoonimisega, t\u00f5usis 4,8 GB\/s. On selgelt n\u00e4ha, et meil on veel reservi, mida me ei kasutanud, kuid hoolimata sellest, saime 20-protsendilisest efektiivsusest 60-protsendilise. <\/p>\n<p>Profilers v\u00f5ivad aidata m\u00f5ista, miks me ei saavutanud 80% v\u00f5i 95%.<\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/4d5904ddf5ed58501ba289b9057f1f09.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nProbleem on selles, et me hoiame maatrikseid vektorite vektorina, st kasutame m\u00e4lule juurdep\u00e4\u00e4su kahekordse tasemega. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/ee069ea2390869099dac90f0ed61f31f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVTune abil on n\u00e4ha, millised k\u00e4sklused on genereeritud massiivi elementide juurde p\u00e4\u00e4semiseks. Vasakul on kollase v\u00e4rvusega esile t\u00f5stetud k\u00e4sklused, mis loevad transpoonitud maatriksi veergude aadresse. Esmalt on need lisak\u00e4sklused ja teiseks lisanduvad andmeedastused. Aga suurematel optimiseerimist\u00f6\u00f6l me ei peatu, l\u00f5petame ja teeme kokkuv\u00f5tte. <\/p>\n<p><img decoding=\"async\" alt=\"C++ optimeerimine: kiirus ja k\u00f5rge tase k\u00e4ivad k\u00e4sik\u00e4es. Yandexi ettekande teema\" src=\"\/wp-content\/uploads\/2020\/10\/d3d821f7b98a49e08a19aeb5eb85edf8.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMille t\u00e4nap\u00e4eval r\u00e4\u00e4kisin? Kasulik n\u00f5uanne arvutuskoodeksiga t\u00f6\u00f6tamiseks on t\u00f6\u00f6tlemine plokkidena, et maandada kulusid, mis on seotud n\u00e4iteks virtuaalsete kutsetega. Plokkide kasutamine parandab ka andmete lokaliteeti, pakkudes meile k\u00f5rgemat ligip\u00e4\u00e4su kiirus. <\/p>\n<p>Allocatsioonide eemaldamine kitsaskohtadest on samuti nende amortiseerimine. See suurendab ligip\u00e4\u00e4su kiirus, lukustades ajutised puhvered m\u00e4lus. <\/p>\n<p>Profiilimise osas. Esiteks on profiilimine kasulik meetod tuvastada kitsaskohad '\u00fcldiselt'. Teiseks v\u00f5imaldab see hinnata koodi efektiivsust, otsustada, kas oleme kiirusest rahul v\u00f5i soovime rohkem optimeerida, ning n\u00e4itab, millises suunas liikuda. <\/p>\n<p>Sellega olen l\u00f5petanud. Kui kasutate CatBoosti v\u00f5i kuulete sellest esmakordselt ja soovite teada, mis see on, \u2013 lugege <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/search\/?target_type=posts&amp;order=relevance&amp;q=%5Bcatboost%5D\">artikleid Habr's<\/a><\/noindex>, tulge meie juurde <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/catboost\/catboost\">GitHub<\/a><\/noindex>, kirjutage meile <noindex><a rel=\"nofollow\" href=\"https:\/\/t.me\/catboost_ru\">Telegraam<\/a><\/noindex>. Suur t\u00e4nu t\u00e4helepanu eest.<br \/>\n<br \/>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/522900\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0427\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043d\u0430 C++ \u0438 \u043a\u0430\u043a \u0435\u0451 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u0434\u0430? \u0412\u0435\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 CatBoost \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041f\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \u044d\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0445 \u0438\u0437 \u043e\u043f\u044b\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 CatBoost \u0434\u043b\u044f x86_64. \u0412\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u2014 \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u042f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f CPU \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f CatBoost. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":97161,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-97160","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0427\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043d\u0430 C++ \u0438 \u043a\u0430\u043a \u0435\u0451 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u0434\u0430? \u0412\u0435\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 CatBoost \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041f\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \u044d\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0445 \u0438\u0437 \u043e\u043f\u044b\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 CatBoost \u0434\u043b\u044f x86_64. \u0412\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u2014 \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u042f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f CPU \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f CatBoost. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f C++: \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c. \u0414\u043e\u043a\u043b\u0430\u0434 \u042f\u043d\u0434\u0435\u043a\u0441\u0430 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0427\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043d\u0430 C++ \u0438 \u043a\u0430\u043a \u0435\u0451 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u0434\u0430? \u0412\u0435\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 CatBoost \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041f\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \u044d\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0445 \u0438\u0437 \u043e\u043f\u044b\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 CatBoost \u0434\u043b\u044f x86_64. \u0412\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u2014 \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u042f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f CPU \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f CatBoost. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-16T12:42:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-16T12:42:31+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47C++ optimeerimine: kiirus ja k\u00f5rge tase koos. Yandexi ettekanne | ProHoster","description":"Mis on C++ programmide t\u00f6\u00f6kiirus ja kuidas seda saavutada k\u00f5rge kooditaseme juures? CatBoosti tegevdirektor Jevgeni Petrov vastas nendele k\u00fcsimustele n\u00e4idete ja illustratsioonide abil oma kogemustest CatBoosti arendamisel x86_64 jaoks. Ettekanne \u2014 Tere k\u00f5igile. Tegele olen CatBoosti masin\u00f5ppe raamatukogu CPU optimeerimisega. Meie raamatukogu p\u00f5hiosa.","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f C++: \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0441\u043e\u043a\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c. \u0414\u043e\u043a\u043b\u0430\u0434 \u042f\u043d\u0434\u0435\u043a\u0441\u0430 | ProHoster","og:description":"\u0427\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043d\u0430 C++ \u0438 \u043a\u0430\u043a \u0435\u0451 \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u0434\u0430? \u0412\u0435\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 CatBoost \u0415\u0432\u0433\u0435\u043d\u0438\u0439 \u041f\u0435\u0442\u0440\u043e\u0432 \u043e\u0442\u0432\u0435\u0442\u0438\u043b \u043d\u0430 \u044d\u0442\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u044f\u0445 \u0438\u0437 \u043e\u043f\u044b\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 CatBoost \u0434\u043b\u044f x86_64. \u0412\u0438\u0434\u0435\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u2014 \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442. \u042f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0434\u043b\u044f CPU \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f CatBoost. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/optimizacziya-c-sovmeshhaem-skorost-i-vysokij-uroven-doklad-yandeksa","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-16T12:42:31+00:00","article:modified_time":"2020-10-16T12:42:31+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"97160","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:25:25","updated":"2022-09-28 12:45:12"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/97160","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=97160"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/97160\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/97161"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=97160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=97160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=97160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}