Profiloinnin taito C++ Sovellukset

Profiloinnin taito C++ Sovellukset

Profiloinnin taito C++ Sovellukset

Johdanto

Esitystyö vetää puoleensa kaksi vastakkaista turhamaisuuden muotoa. Yksi insinööri haluaa uskoa, että intuitio riittää, että hyvä nenä kuumalle koodille voi korvata todisteet. Toinen haluaa uskoa, että profiloijan kuvakaappaus on itsessään johtopäätös, ikään kuin mittauspainikkeen painaminen muuttaisi hämmennyksen tiedoksi. Molemmat vaistot ovat vietteleviä, ja molemmat aiheuttavat vahinkoa.

Profiling in C++ is valuable precisely because C++ gives us so much room to be plausibly wrong. Hidas järjestelmä voi todellakin kärsiä välimuistin puuttumisesta, lukituskiistasta, allokaattorin vaihtumisesta, haaroittavista kuumasilmukoista, vektorisoinnin estäjistä tai liian monista kopioista. It may also be waiting on I/O while everyone in the room argues about CPU. It may be spending more time serializing results than computing them. It may be scaling badly because threads keep colliding in ways no code comment warned us about. In a language this expressive and this close to the machine, plausible explanations multiply quickly.

Siksi profilointi on ymmärrettävä rehellisyyden kurinalaiseksi. Se opettaa korvaamaan tyylikkäät tarinat mitatuilla tarinoilla. Se hidastaa uudelleenkirjoittamisen kiirettä. Se pelastaa tiimit tuhlaamasta viikkoa parantamaan jotain, mikä osoittautui vain neljäksi prosentiksi ongelmasta. And when done well, it has a surprisingly humane effect on engineering culture, because it makes arguments less theatrical and more collaborative. Profiloijasta tulee erotuomari.

Profilointi alkaa ennen työkalun avaamista

Hyödyllinen profilointiistunto alkaa kauan ennen kuin ensimmäinen näyte on kerätty. Se alkaa, kun päätämme, mihin kysymykseen yritämme vastata. "Miksi ohjelma on hidas?" ei ole koskaan tarpeeksi hyvä kysymys. Se on liian epämääräinen ohjaamaan työkalun valintaa ja liian epämääräinen väärennettäväksi. Paremmat kysymykset kuulostavat konkreettisemmilta. Miksi p99-latenssi regressi jäsentimen vaihdon jälkeen? Miksi suorituskyvyn paraneminen lakkaa kahdeksan säikeen jälkeen? Miksi yksi koneluokka käyttäytyy huonommin kuin toinen? Miksi koodin yksinkertaistaminen teki binaarista hitaamman kuormituksen aikana?

Kysymyksen laatu määrittää muun työn. Jos oireena on pyyntöviiveen regressio, tarvitsemme edustavia pyyntöpolkuja ja selkeän määritelmän siitä, missä tämä latenssi havaitaan. Jos oireena on suorituskyvyn tasanne, meidän on tiedettävä, rajoittavatko CPU, odotus, muistin kaistanleveys tai synkronointi kasvua. Jos oire on konekohtainen, laitteiston laskurit, affiniteetti ja käyttöönottoerot voivat olla tärkeämpiä kuin itse lähdekoodi. Hyvän kysymyksen esittäminen on jo eräänlaista optimointia, koska se kaventaa niiden asioiden kenttää, joissa olemme valmiita olemaan väärässä.

Tämä on myös paikka, jossa monet joukkueet sabotoivat hiljaa itseään. Ne profiloituvat epärealistisen kuormituksen alaisena, väärällä binäärillä, lelutuloilla, ympäristössä, joka on niin meluisa, että mittauksista tulee teatteria. Sitten he esittävät tuloksia tähtitieteen luottamuksen ja sääperinteen todisteiden laadulla. Profiloija ei pettänyt heitä. Heidän kokeilusuunnitelmansa epäonnistui. Suoritustyössä ankaruus alkaa asennuslinjalta.

Luo mittausympäristö, johon voit luottaa

C++-ohjelmat paljastavat erilaisia ​​persoonallisuuksia eri olosuhteissa. Virheenkorjausversio voi näyttää tuhoisan hitaalta syistä, joilla ei ole mitään tekemistä tuotannon kanssa. Julkaisuversio ilman symboleja voi toimia riittävän nopeasti, mutta piilottaa polun, joka meidän on nähtävä. Pieni synteettinen syöttö saattaa sopia välimuistiin niin täydellisesti, että se imartelee huonoa suunnittelua. Lämpöpaineen tai taustamelun alainen kone voi tuottaa tuloksia, jotka tuntuvat täsmällisiltä, ​​vaikka ne kuvaavat satunnaisia ​​häiriöitä.

Luotettava ympäristö voi olla epätäydellinen; sen täytyy olla tahallista. Käytä binaaritiedostoa, joka on lähinnä sitä, mitä käyttäjät todellisuudessa käyttävät. Säilytä virheenkorjaustiedot tai kehysosoittimet siellä, missä työkalusi hyötyvät niistä. Syötä ohjelmaan realistisia syötteitä tai ainakin syötteitä, jotka säilyttävät todellisen työkuorman laadulliset ominaisuudet: tietokoot, haaran epäsäännöllisyydet, kilpailumallit, allokointipaineet ja pyyntöjen yhdistelmä. Mittaa keskimääräistä ajonaikaa ja järjestelmälle tärkeitä lähdöt: loppuviive, suoritusteho, vaiheen aika, varauksen määrä, lukituksen odotus, välimuistin käyttäytyminen tai käynnistysaika ongelmasta riippuen.

Tämän hyvin tekemisessä on syvää ystävällisyyttä. Kun insinööri profiloi rehellisissä olosuhteissa, hän säästää koko tiimin taistelulta haamuista. Virheellinen asetus saa kaikki puolustamaan teorioita. Hyvä järjestely antaa teorioiden kuolla nopeasti. Se on yksi kustannustehokkaimmista lahjoista, jonka suorituskykyinen insinööri voi antaa projektille.

Opi erottamaan työ odottamisesta

Yksi yleisimmistä profiloinnin epäonnistumisista on käsitellä kaikkea hitautta ikään kuin se olisi CPU työtä. C++-insinöörit ovat erityisen alttiita tälle virheelle, koska kieli kutsuu matalan tason ajatteluun. Jos palvelu on hidas, alamme kuvitella ohjeita, haaroja, välimuistirivejä ja sisäisiä päätöksiä. Joskus tämä vaisto on aivan oikea. Muina aikoina järjestelmä enimmäkseen odottaa: odottaa lukoissa, odottaa jonoissa, odottaa I/O:ta, odottaa ylikoordinoituja säieryhmiä, odottaa resurssia, jota hot loop ei voi korjata muuttumalla hieman kauniimmaksi.

Hyvä profilointi alkaa siis laajalta ja muuttuu mikroskooppiseksi vasta, kun laaja kuva on selvä. Näytteenottoprofiloijat ovat erinomaisia ​​selvittämään, minne CPU aika todellisuudessa menee. Jäljitystyökalut auttavat paljastamaan, milloin ongelma todella liittyy sekvensointiin, odottamiseen tai vaiheittaiseen vuorovaikutukseen. Kasa- ja allokointityökalut kertovat, saastuttaako muistitarina kaikkea muuta. Laitteistolaskurit ovat hyödyllisiä, kun polku on todella tarpeeksi kuuma, jotta poikkeamat, haarat, spekulaatiot tai vektorisoinnin laatu ansaitsevat huomiota. Jokainen työkalu on tapa esittää erilainen kysymys. Ongelmat alkavat, kun tiimit esittävät yhden kysymyksen ja tulkitsevat vastauksen ikään kuin se ratkaisisi toisen.

Tuttu esimerkki havainnollistaa ansaa. Oletetaan, että jäsentäjä näkyy CPU-profiilin yläosassa. Kärsimätön insinööri voi päätellä, että jäsentäjä on kirjoitettava uudelleen. Aikajananäkymä saattaa kuitenkin osoittaa, että jäsentäjä näyttää hallitsevalta vain siksi, että liukuhihnan muu osa on usein tukossa, jolloin aktiivinen CPU-alue näyttää suhteellisesti suuremmalta kuin se todellisuudessa on. Toisessa tapauksessa jäsentäjä on todella kallis, mutta pieni kohdennettu muutos allokaatioissa poistaa suurimman osan kustannuksista ilman dramaattisia uudelleenkirjoituksia. Profiloijan lahja ei ole se, että se kertoo meille, mitä optimoidaan yhdessä vaiheessa. Sen lahja on, että se erottaa jatkuvasti olennaisen työn teatterityöstä.

Työkalulla on vähemmän merkitystä kuin tulkinnalla

Insinöörit kysyvät usein, mikä profiloija on paras, ikään kuin siinä olisi universaalisti oikea vastaus. Käytännössä parempi kysymys on, millaista totuutta tarvitset seuraavaksi. Visual Studio, VTune, Visual Studio:n profiloijat, Tracy, Perfetto, liekkikaaviot, Callgrind ja kasaprofiloijat valaisevat kukin erilaista todellisuuden pintaa. Aikuinen tapa ei ole työkaluuskollisuus. Se on tulkitsevaa kurinalaisuutta.

Liekkikaavio on loistava näyttämään, missä CPU-näytteet kerääntyvät, mutta se ei selitä jonotusviivettä sinänsä. Aikajananäkymä on erinomainen näyttämään vaiheiden vuorovaikutusta ja odottamista, mutta se ei välttämättä kerro, miksi tiukka silmukka kärsii haaravirheistä. Kasaprofiili voi paljastaa allokointivaihtuvuuden, joka myrkyttää koko polun, mutta se ei kuitenkaan ratkaise itse, onko lankamallisi johdonmukainen. Insinööreistä tulee vaarallisia, kun he sekoittavat työkalun visuaalisen vetovoiman ymmärryksen täydellisyyteen.

Tästä syystä profiloinnilla on taiteellista ulottuvuutta, vaikka se rakentuu mittaamiseen. Taide ei ole mystiikkaa. Se on tuomio. Se tietää, milloin hotspot on ensisijainen ja milloin toissijainen, milloin mikrobenchmark on rehellinen ja milloin se imartelee työn väärää muotoa, milloin laitteistolaskuri ansaitsee luottamuksen ja milloin sen pitäisi vain herättää uusi kokeilu. Se on myös tieto, milloin lopettaa alaspäin kaivaminen ja sen sijaan yksinkertaistaa arkkitehtuuria, joka teki mittauksista alun perin rumia.

C++:n suorituskykyongelmien tyypilliset muodot

C++ suorituskykyongelmat jakautuvat usein tunnistettavissa oleviin perheisiin. Jotkut ovat yksinkertaisesti laskennallisia: tiukat silmukat tekevät liikaa työtä, huono vektorointi, haaroittamaton kuuma koodi tai tietorakenteet, jotka ovat huonosti vuorovaikutuksessa välimuistin kanssa. Jotkut ovat muistin muotoisia: liian monta varausta, epävakaat omistusmallit, tarpeettomat kopiot, pirstoutuminen tai asettelut, jotka hajottavat kuumaa dataa, kunnes CPU viettää enemmän aikaa odottamiseen kuin laskemiseen. Jotkut ovat koordinaatioongelmia: vaarattomalta näyttäneet lukot, jonot, jotka lisäsivät yhden ylimääräisen hypyn liikaa, työn varastaneet mallit, jotka auttoivat keskimääräistä suorituskykyä ja heikensivät hännän käyttäytymistä, tai lankojen määrä, joka ylittää arkkitehtuurin kyvyn pysyä järjestyksessä.

Profiloinnista tekee tehokkaan se, että nämä perheet naamioituvat usein toisikseen. Muistiongelma voi näyttää CPU-ongelmalta. Odotusongelma voi näyttää algoritmiselta ongelmalta. Kirjauspolku voi näyttää merkityksettömältä, kunnes loppuviivenäkymä osoittaa sen saastuttaneen koko palvelun. Triviaalin näköisellä kopiolla voi olla merkitystä vain siksi, että se esiintyy yhdessä paikassa, johon pyyntöpolulla ei ole varaa. Ilman mittausta nämä vuorovaikutukset on helppo kertoa ja vaikea luokitella.

Hyvä profiloija kehittää siten mittasuhteen makua. Kaikilla tehottomuudella ei ole merkitystä. Kaikki rumat toiminnot eivät ole pelastamisen arvoisia. Kaikki puhtaat toiminnot eivät ole viattomia. Ohjelma opettaa meille, missä arvokkuus ja kiireellisyys kohtaavat, ja usein tämä paikka ei ole siellä, missä koodin tarkistaja ensin osoitti.

Tapaustutkimus väärästä diagnoosista

Kuvittele palvelu, joka kerää tietueita, normalisoi ne, pisteyttää ne ja lähettää tuloksia. Julkaisun jälkeen suorituskyky laskee ja p99-viive pahenee. Ensimmäinen teoria huoneessa on, että uusi pisteytysrutiini esitteli kalliin matematiikan. Toinen teoria on, että jäsentäjä on nyt liian haarautunut. Kolmas on, että allokaattori regressi kirjaston päivityksen jälkeen. Jokainen teoria on tarpeeksi uskottava kuulostaakseen älykkäältä kokouksessa.

Laaja CPU-profiili osoittaa, että jäsentäjä ja pisteytys vievät molemmat näkyvää aikaa, mutta eivät tarpeeksi selittämään koko latenssiregressiota. Aikajanan jäljitys paljastaa odotuspurskeet jaetun tulostevaiheen ympärillä. Keon analyysi näyttää toistuvan allokoinnin ja muotoilun työt lähellä pyyntöpolun loppua. Pieni kokeilu, joka säilyttää säiettäkohtaiset puskurit ja lykkää muotoilua, tiivistää odotuskuvion ja poistaa yllättävän määrän loppuviivettä. Vasta sen jälkeen tarkennettu CPU-profiili osoittaa, että maalintekijä ansaitsee edelleen pienemmän siivouksen kopioista, jotka tulivat näkyviin, kun suurempi pullonkaula oli poistunut.

Tämä on tavallinen tarina, ja juuri siksi sillä on merkitystä. Todellinen profilointi päättyy harvoin yhteen dramaattiseen roistoon. Useimmiten se paljastaa pinon tavallisia kustannuksia, joista kutakin täydentävät muut. Insinööri, joka odotti yhtä elokuvallista korjausta, oppii sen sijaan, kuinka järjestelmät itse asiassa heikkenevät: kerääntymisen, vuorovaikutuksen ja laiminlyötyjen mittasuhteiden kautta. Tämä oppitunti on arvokkaampi kuin mikään yksittäinen vauhti, koska se muuttaa tulevien tutkimusten alkamista.

Profilointi joukkueen tapana

Parhaat tiimit rakentavat profiloinnin katsauksiksi, regressioiksi ja suuriksi suunnittelumuutoksiksi. They keep representative datasets. Ne tallentavat liekkikaavioita, jälkiä ja benchmark-artefakteja sekä selityksiä siitä, mikä muuttui. He tekevät normaaliksi kysyä, muuttaako ehdotettu yksinkertaistaminen allokaatioita, hännän latenssia tai vaiherajoja. He kunnioittavat suorituskykyä tarpeeksi mitatakseen sitä ennen kuin puhuvat liian kovaa.

Tämä tapa muuttaa koodikannan tunne-elämää. Insinööreistä tulee vähemmän puolustava, koska profilointi ulkoistaa ongelman. Hidas järjestelmä ei ole enää syytös viimeistä koodiin koskenutta henkilöä vastaan. Siitä tulee yhteinen arvoitus todisteineen. Jopa nuoremmat insinöörit tulevat tehokkaammiksi tässä ympäristössä, koska he oppivat luottamaan kysymyksiin ja kokeiluihin yli arvostuksen. Näin rakennettu esityskulttuuri on rauhallisempi.

Siksi profiloinnin taidolla on niin paljon merkitystä C++:ssa. Kieli antaa meille voimaa rakentaa erinomaisia ​​järjestelmiä, mutta huippuosaamista ei synny pelkästään älykkyydestä. Se syntyy toistuvista, kurinalaisista havaitsemistoimista. Profilointi on yksi parhaista tavoista, joilla insinöörit oppivat huomaamaan, mitä kone on koko ajan yrittänyt sanoa.

Hands-On Lab: Profiloi tarkoituksellisesti tehoton ohjelma

Rakentakaamme pieni ohjelma, joka on tarkoituksella hieman typerää. Siitä on hyötyä, sillä todellinen profilointitaito oppii nopeimmin, kun virheet ovat tarpeeksi konkreettisia löydettäväksi.

main.cpp

#include <algorithm>
#include <chrono>
#include <iostream>
#include <mutex>
#include <random>
#include <string>
#include <thread>
#include <vector>

std::mutex g_lock;

static std::string make_payload(std::mt19937& rng) {
    std::uniform_int_distribution<int> len_dist(20, 120);
    std::uniform_int_distribution<int> ch_dist(0, 25);

    std::string s;
    const int len = len_dist(rng);
    for (int i = 0; i < len; ++i) {
        s.push_back(static_cast<char>('a' + ch_dist(rng)));
    }
    return s;
}

static uint64_t score_payload(const std::string& s) {
    uint64_t total = 0;
    for (char c : s) {
        total += static_cast<unsigned char>(c);
    }
    return total;
}

int main() {
    constexpr size_t N = 400000;
    std::vector<std::string> rows;
    rows.reserve(N);

    std::mt19937 rng{42};
    for (size_t i = 0; i < N; ++i) {
        rows.push_back(make_payload(rng));
    }

    std::vector<uint64_t> out;
    out.reserve(N);

    auto worker = [&](size_t begin, size_t end) {
        for (size_t i = begin; i < end; ++i) {
            auto copy = rows[i];
            std::sort(copy.begin(), copy.end());
            uint64_t value = score_payload(copy);

            std::lock_guard<std::mutex> guard(g_lock);
            out.push_back(value);
        }
    };

    const auto t0 = std::chrono::steady_clock::now();

    std::thread t1(worker, 0, N / 2);
    std::thread t2(worker, N / 2, N);
    t1.join();
    t2.join();

    const auto t1_end = std::chrono::steady_clock::now();
    const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t1_end - t0).count();

    std::cout << "done in " << ms << " ms, values=" << out.size() << "\n";
}

Tämä ohjelma sisältää useita klassisia esityksen tuoksuja:

  • toistuvia merkkijonokopioita
  • turhaa lajittelua kuumalla polulla
  • keskuslukituskiista ulostulossa
  • raskas merkkijonojen sukupolvi

Rakenna profilointia varten

Linux:

g++ -O2 -g -fno-omit-frame-pointer -std=c++20 -pthread -o bad_profile main.cpp

Windows ja MSVC:

cl /O2 /Zi /std:c++20 main.cpp

Ensimmäinen profiili

Linux:

perf record -g ./bad_profile
perf report

Tai kerää liekkikaavio, jos se on osa työnkulkuasi.

Mitä sinun pitäisi huomata

Hyvän profiilin pitäisi nopeasti vihjata, että järjestelmä ei kärsi yhdestäkään mystisestä ongelmasta. Se kärsii joukosta hyvin tavallisia teknisiä valintoja. Se on oikea opetus.

Testitehtävät harrastajille

  1. Poista keskimmäinen mutex käyttämällä yhtä lähtövektoria säiettä kohti. Mittaa uudelleen.
  2. Poista tarpeeton std::sort ja vahvista, kuinka suuri osa kustannuksista oli teatteriesityksiä välttämättömien sijaan.
  3. Korvaa auto copy = rows[i]; pienemmällä versiolla ja tarkista, muuttuuko profiili odotetulla tavalla.
  4. Kasvata lankojen määrää ja tarkkaile, onko läpimenoasteikko vai hallitseeko koordinaatio.
  5. Rakenna sama ohjelma koodilla -fno-omit-frame-pointer ja ilman sitä ja vertaa pinojen laatua.

Jos suoritat nämä viisi vaihetta huolellisesti, olet oppinut jotain paljon arvokkaampaa kuin profilointityökalujen nimet. Olet oppinut kuinka huono teoria kuolee mittauksen läsnä ollessa.

Yhteenveto

C++-sovellusten profiloinnin taito on rehellisyyden taitoa.

Hyvä profilointi ei tarkoita hienoimpien kuvakaappausten keräämistä tai jokaisen laitteistolaskurin muistamista. Kyse on tarkkojen kysymysten esittämisestä, mittaamisesta realistisissa olosuhteissa, CPU-työn erottamisesta odottamisesta, muistin käyttäytymisen ymmärtämisestä ja oikean työkalun käyttämisestä ongelman oikeaan kerrokseen.

Käytä näytteenottoa löytääksesi laaja CPU totuus. Käytä jäljitystä ymmärtääksesi aikaa ja koordinaatiota. Käytä kekoanalyysiä, kun allokointikäyttäytyminen hallitsee. Käytä laitteistolaskuria, kun välimuistit ja spekulaatiot muuttuvat todelliseksi tarinaksi. Ja ennen kaikkea profiili ennen optimointia.

C++:ssa tämä kurinalaisuus on usein ero elegantin, korkean suorituskyvyn suunnittelun ja kalliin taikauskon välillä.

Viitteet

  1. Linux Linux -man sivu: https://man7.org/linux/man-pages/man1/perf.1.html
  2. Linux Linux -man sivu: https://man7.org/linux/man-pages/man1/perf-stat.1.html
  3. Intel VTune Profiler -dokumentaatio: https://www.intel.com/content/www/us/en/docs/vtune-profiler/overview.html
  4. Visual Studio -profiilin esittely: Visual Studio
  5. Tracy Profiler -tietovarasto: https://github.com/wolfpld/tracy
  6. Perfetto-dokumentaatio: https://perfetto.dev/docs/
  7. Brendan Greggin liekkikaaviot: https://www.brendangregg.com/flamegraphs.html
  8. Callgrind-opas: https://valgrind.org/docs/manual/cl-manual.html
  9. Heaptrack-arkisto: https://github.com/KDE/heaptrack
  10. AddressSanitizerin dokumentaatio: https://clang.llvm.org/docs/AddressSanitizer.html

    Miltä tämä näyttää, kun järjestelmä on jo paineen alainen

C++-profilointikäytännöstä tulee yleensä kiireellinen juuri sillä hetkellä, kun joukkue toivoi hiljaisempaa neljännestä. Ominaisuus on jo asiakkaiden edessä tai alustalla on jo sisäinen riippuvuus, ja järjestelmä on valinnut kyseisen viikon paljastaakseen, että sen elegantti teoria ja sen ajonaikainen käyttäytyminen ovat eläneet kohteliaasti erillistä elämää. Tästä syystä niin moni vakava insinöörityö alkaa sovinnolla. Tiimin on sovitettava yhteen se, mitä se uskoo järjestelmän tekevän, sen kanssa, mitä järjestelmä todella tekee kuormitettuna, muutoksen aikana ja sellaisissa määräajoissa, jotka tekevät kaikista hieman luovempia ja hieman vähemmän viisaita.

Tuotannon suorituskyvyn suunnittelussa tärkeimmät tapaukset ovat yleensä keskiarvojen piilottamat latenssipiikit, huonojen testityökuormien peittämät CPU-hotspotit ja liian myöhään havaitut muistiregressiot. Näillä tilanteilla on teknisiä, budjetti-, luottamus-, tiekartta- ja joskus mainevaikutuksia. Tekninen ongelma kasvaa poliittisesti suuremmiksi sillä hetkellä, kun useat tiimit ovat riippuvaisia ​​siitä, eikä kukaan voi selittää, miksi se käyttäytyy edelleen kuin pesukarhu seinien sisällä: meluisa yöllä, vaikea paikantaa ja kallis jättää huomiotta.

Siksi suosittelemme lukemaan ongelman käyttöpaineen ja toimitustodellisuuden linssin läpi. Suunnittelu voi olla teoreettisesti kaunis ja toiminnallisesti tuhoisa. Toinen malli voi olla melkein tylsä ​​ja silti viedä tuotetta eteenpäin vuosia, koska se on mitattavissa, korjattavissa ja rehellinen kompromissiensa suhteen. Vakavat insinöörit oppivat pitämään parempana toista luokkaa. Se tekee vähemmän eeppisiä puheita, mutta myös vähemmän hätätapahtumia, joissa kaikki puhuvat passiivisella äänellä eikä kukaan muista, kuka hyväksyi pikakuvakkeen.

Käytännöt, jotka vanhenevat jatkuvasti hyvin

Ensimmäinen kestävä käytäntö on pitää yksi edustava polku jatkuvassa mittauksessa. Ryhmät keräävät usein liian paljon epämääräistä telemetriaa ja liian vähän päätöslaatuista signaalia. Valitse polku, jolla on aidosti merkitystä, mittaa sitä toistuvasti ja kieltäydy antamasta keskustelua ajautua koristeelliseen tarinankerrontaan. C++-profilointikäytännössä hyödyllisiä mittareita ovat yleensä edustavat työmäärät, jäljityksen laatu, kuumapolun vakaus ja löydösten toistettavuus. Kun ne ovat näkyvissä, loput päätökset muuttuvat inhimillisemmiksi ja vähemmän mystisiksi.

Toinen kestävä käytäntö on erottaa todiste lupauksesta. Insinöörejä painostetaan usein sanomaan, että suunta on oikea, ennen kuin järjestelmä on ansainnut tämän johtopäätöksen. Vastusta sitä painetta. Rakenna ensin kapea todiste, varsinkin kun aihe on lähellä asiakkaita tai rahaa. Pienellä todennetulla parannuksella on enemmän kaupallista arvoa kuin suurella todentamattomalla kunnianhimolla. Tämä kuulostaa itsestään selvältä, kunnes vuosineljänneksen lopun tarkastelu muuttaa hypoteesin määräajaksi ja koko organisaatio alkaa kohdella optimismia kuin aikataulutusartefaktia.

Kolmas kestävä käytäntö on kirjoittaa suositukset omistajakielellä. Kappale, jossa sanotaan "parantaa suorituskykyä" tai "vahvistaa rajoja", on emotionaalisesti miellyttävä ja toiminnallisesti hyödytön. Kappale, joka kertoo kuka muuttaa mitä, missä järjestyksessä, millä palautusehdon kanssa, on se, joka todella selviää maanantaiaamuna. Täällä monet tekniset kirjoittamiset epäonnistuvat. Se haluaa kuulostaa enemmän edistyneeltä kuin se haluaa olla aikataulutettu.

Vastaesimerkkejä, jotka säästävät aikaa

Yksi yleisimmistä vastaesimerkeistä näyttää tältä: tiimillä on jyrkkä paikallinen menestys, oletetaan, että järjestelmä on nyt ymmärretty, ja sitten skaalaa idean paljon vaativampaan ympäristöön ilman, että mittauskuria päivitetään. Se on tekninen vastine, kun opetellaan uimaan hotellin uima-altaassa ja sitten pidettäisiin itsevarma TED-puhe meren säästä. Vesi on vettä, kunnes sitä ei ole.

Toinen vastaesimerkki on työkalujen inflaatio. Uusi profiloija, uusi ajonaika, uusi kojelauta, uusi agentti, uusi automaatiokerros, uusi kääre, joka lupaa harmonisoida vanhan kääreen. Mikään näistä asioista ei ole luonnostaan ​​huono. Ongelmana on, mitä tapahtuu, kun heitä pyydetään kompensoimaan rajaa, jota kukaan ei ole nimennyt selvästi. Järjestelmästä tulee sitten instrumentoidumpi, vaikuttavampi ja vain toisinaan ymmärrettävämpi. Ostajat tuntevat tämän hyvin nopeasti. Jopa ilman tätä ilmaisua he voivat haistaa, kun pinosta on tullut kallis korvike päätökselle.

Kolmas vastaesimerkki on ihmisen tarkastelun käsitteleminen automaation epäonnistumisena. Todellisissa järjestelmissä ihmisen tarkastelu on usein ohjaus, joka pitää automaation kaupallisesti hyväksyttävänä. Aikuiset tiimit tietävät, missä automatisoida aggressiivisesti ja missä pitää hyväksyntä tai tulkinta näkyvänä. Epäkypsät tiimit haluavat koneen tekevän kaiken, koska "kaikki" kuulostaa tehokkaalta diassa. Sitten tapahtuu ensimmäinen vakava tapaus, ja yhtäkkiä manuaalinen tarkistus löydetään uudelleen konversiokokemuksen vilpittömästi.

Suosittelemamme toimitusmalli

Jos työ on tehty hyvin, ensimmäisen suorituksen pitäisi vähentää stressiä antamalla tiimille riittävän vahva tekninen lukema, jotta se lopettaa kiistelyn. Sen jälkeen seuraavan rajoitetun toteutuksen pitäisi parantaa yhtä ratkaisevaa polkua, ja uudelleentestauksen pitäisi tehdä suunta luettavaksi sekä suunnittelulle että johdolle. Tämä järjestys on tärkeämpi kuin tarkka työkaluvalinta, koska se muuttaa teknisen taidon eteenpäinliikkeeksi.

Käytännössä suosittelemme kapeaa ensimmäistä sykliä: kerää esineitä, tee yksi kova diagnoosi, lähetä yksi rajoitettu muutos, testaa todellinen polku uudelleen ja kirjoita seuraava päätös selkeällä kielellä. Selkeällä kielellä on väliä. Ostaja harvoin katuu selkeyttä. Ostaja katuu usein olevansa vaikuttunut ennen kuin kuitit saapuvat.

Tässä myös sävyllä on väliä. Vahvan teknisen työn pitäisi kuulostaa siltä kuin se on kohdannut tuotannon ennenkin. Rauhallinen, tarkka ja hieman huvittunut hypeistä sen sijaan, että se ravitsee sitä. Tämä ääni välittää toimintasignaalin. Se osoittaa, että tiimi ymmärtää järjestelmäsuunnittelun vanhan totuuden: koneet ovat nopeita, tiekartat ovat hauraita, ja ennemmin tai myöhemmin lasku saapuu jokaisesta olettamuksesta, jonka annettiin pysyä runollisena.

Tarkistuslista, jota käyttäisimme ennen kuin kutsumme tämän valmiiksi

Tuotannon suorituskyvyn suunnittelussa valmius ei ole mieliala. Se on tarkistuslista, jolla on seurauksia. Ennen kuin kutsumme C++-profilointikäytäntöjä valmiiksi laajempaan käyttöönottoon, haluamme, että muutama asia on tylsää parhaalla mahdollisella tavalla. Haluamme yhden polun, joka käyttäytyy ennustettavasti edustavan kuormituksen alla. Haluamme yhden mittasarjan, joka ei ole ristiriidassa itsensä kanssa. Haluamme joukkueen tietävän, missä raja menee ja mitä sen rikkominen merkitsisi. Ja haluamme työn tulosten olevan riittävän selkeitä, jotta joku toteutushuoneen ulkopuolella voi silti tehdä siitä järkevän päätöksen.

Tämä tarkistuslista koskettaa yleensä edustavia työkuormia, jäljityksen laatua, kuumapolun vakautta ja löydösten toistettavuutta. Jos luvut liikkuvat oikeaan suuntaan, mutta tiimi ei silti osaa selittää järjestelmää improvisoimatta, työ ei ole valmis. Jos arkkitehtuuri kuulostaa vaikuttavalta, mutta ei kestä vaatimatonta vastaesimerkkiä kentältä, teos ei ole valmis. Jos toteutus on olemassa, mutta palautustarina kuulostaa rukoukselta aikaleimoineen, teos ei ole valmis. Mikään näistä ei ole filosofisia vastaväitteitä. Ne ovat yksinkertaisesti muotoja, joissa kalliilla yllätyksillä on tapana esitellä itsensä.

Täällä myös tiimit huomaavat, ratkoivatko he todellista ongelmaa vai vain harjoittelivat osaamista sen yleisessä läheisyydessä. Monet tekniset ponnistelut tuntuvat onnistuneilta, kunnes joku pyytää toistettavuutta, tuotantotodisteita tai päätöstä, joka vaikuttaa budjettiin. Sillä hetkellä heikko työ hämärtyy ja vahva työ muuttuu oudon selväksi. Plain on hyvä. Pelkkä tarkoittaa yleensä sitä, että järjestelmä on lakannut luottamasta karismaan.

Kuinka suosittelemme puhumaan tuloksista

Lopullisen selityksen tulee olla riittävän lyhyt selviytyäkseen johtajuuden kokouksesta ja riittävän konkreettinen selviytyäkseen teknisestä katsauksesta. Se on vaikeampaa kuin miltä se kuulostaa. Liian tekninen kieli piilottaa järjestyksen. Liian yksinkertaistettu kielenkäyttö piilottaa riskin. Oikea keskitie on kuvata polkua, todisteita, rajallista muutosta ja seuraavaa suositeltua askelta tavalla, joka kuulostaa mieluummin rauhalliselta kuin voittoisalta.

Suosittelemme tällaista rakennetta. Sano ensin, mitä polkua arvioitiin ja miksi sillä oli merkitystä. Toiseksi sano, mikä oli vialla tai epävarmaa kyseisessä polussa. Kolmanneksi sano, mitä muutettiin, mitattiin tai vahvistettiin. Neljänneksi sano, mikä on vielä ratkaisematta ja mitä seuraava sijoitus ostaisi. Tämä rakenne toimii, koska se kunnioittaa sekä suunnittelua että ostokäyttäytymistä. Insinöörit haluavat yksityiskohtia. Ostajat haluavat sekvensoinnin. Kaikki haluavat vähemmän yllätyksiä, myös ihmiset, jotka teeskentelevät nauttivansa niistä.

Tällä tavalla puhumisen piilotettu hyöty on kulttuurinen. Tiimit, jotka selittävät teknisen työn selkeästi, tekevät sen yleensä myös selkeämmin. He lakkaavat käsittelemästä monitulkintaisuutta hienostuneisuutena. Heihin on vaikeampi tehdä vaikutuksen ammattikieltä ja helpompi luottaa vaikeiden järjestelmien kanssa. Se on yksi insinööritaidon aliarvostetuimmista muodoista.

Mitä emme edelleenkään kieltäytyisi väärentämästä

Jopa järjestelmän parantumisen jälkeen kypsät tiimit pitävät epävarmuuden rehellisenä tuotannon suorituskyvyn suunnittelussa. Heikko mittaus vaatii selkeämpää näyttöä, kovat rajat selkeää kieltä ja rauhallisemmat demot todellista toimintavalmiutta. Epävarmuutta on vähennettävä; jotkut on nimettävä rehellisesti. Nämä kaksi tehtävää sekoitetaan siinä, kuinka kunniallisista projekteista tulee kalliita vertauksia.

Sama sääntö koskee C++-profilointikäytäntöjä koskevia päätöksiä. Jos tiimiltä puuttuu edelleen toistettava vertailukohta, luotettava palautuspolku tai selkeä omistaja kriittiselle käyttöliittymälle, hyödyllisin tulos voi olla terävämpi ei tai kapeampi seuraava askel suuremman lupauksen sijaan. Tämä kurinalaisuus pitää teknisen työn linjassa sen todellisuuden kanssa, jota sen on tarkoitus parantaa.

Tällä työskentelyllä on outo helpotus. Kun järjestelmä ei enää ole riippuvainen optimistisesta tarinankerronnasta, insinöörikeskustelu yksinkertaistuu, vaikka työ olisikin kovaa. Ja tuotannossa se on usein vähäistä armon muotoa.

Lisähuomautuksia profilointityöstä

Hyvä profilointitulos ei ole kaunis liekkikaavio. Se on kapea päätös. Työn luovutushetkellä tiimin pitäisi tietää, mikä työmäärä on edustava, mikä hotspot on kausaalinen, mikä löydös on melu ja mihin optimointiin kannattaa koskea ensin. Se kuulostaa vakavalta, mutta vakavuus on hyödyllistä tässä. Esitystyö tulee kalliiksi sillä hetkellä, kun kaikki näkevät lämpöä, eikä kukaan pääse yksimielisyyteen, mikä tuli on tärkeä.

Suosittelemme myös kirjaamaan muistiin epäkorjaukset. Se on oudon voimakas kurinalaisuus. Kerro selvästi, mitkä epäilyttävät toiminnot mitattiin ja vapautettiin, mikä allokaattoriteoria ei selvinnyt jäljestä ja mikä dramaattinen uudelleenkirjoitusehdotus osoittautui tarpeettomaksi. Insinöörit rauhoittuvat, kun umpikujat nimetään. Johtamisesta tulee rauhallisempaa, kun se näkee tiimin optimoivan todisteiden mukaan mielialan sijaan. C++-järjestelmissä rauhallisuus on aliarvostettua. Se saapuu usein naamioituna testivaljaiksi ja muistikirjaksi, joka on täynnä vähemmän romanttisia faktoja.

Kentän muistiinpanot todellisesta teknisestä katsauksesta

C++-järjestelmätoimituksessa työ muuttuu vakavaksi, kun demo kohtaa todellisen toimituksen, todelliset käyttäjät ja todelliset käyttökustannukset. Se on hetki, jolloin siisti idea alkaa käyttäytyä kuin järjestelmä, ja järjestelmillä on tunnetusti kuiva huumorintaju. He eivät välitä siitä, kuinka tyylikkäältä aloituspakka näytti. He välittävät rajoista, vikatiloista, käyttöönottopoluista ja siitä, voiko kukaan selittää seuraavan vaiheen keksimättä uutta mytologiaa pinon ympärille.

The Art of Profiling C++ Applications:n kohdalla käytännön kysymys on, luoko se vahvemman toimituspolun ostajalle, jolla on jo paineita etenemissuunnitelman, alustan tai tietoturvatarkastuksen suhteen. Tuo ostaja ei tarvitse sumuksi kiillotettua luentoa. He tarvitsevat teknisen luennon, jota he voivat käyttää.

Mitä tarkastaisimme ensin

Aloitamme yhdellä edustavalla polulla: natiivi päättely, profilointi, HFT-polut, DEX-järjestelmät ja C++/Rust-modernisointivaihtoehdot. Tuon polun tulee olla tarpeeksi kapea mitatakseen ja riittävän leveä paljastaakseen totuuden. Ensimmäisen läpimenon pitäisi tallentaa allokointikäyttäytyminen, p99-viive, profiilin todisteet, ABI kitka ja vapauttaa luottamus. Jos nämä signaalit eivät ole saatavilla, projekti on edelleen enimmäkseen mielipidettä laboratoriotakissa, ja mielipiteellä on pitkä historia laskuttaa itsensä strategiana.

Ensimmäinen hyödyllinen artefakti on alkuperäisten järjestelmien luku, jossa on vertailuarvoja, profilointitodistusta ja laajennettu toteutussuunnitelma. Sen pitäisi näyttää järjestelmä sellaisena kuin se käyttäytyy, ei niin kuin kaikki toivoivat sen käyttäytyvän suunnittelukokouksessa. Jäljitys, toisto, pieni benchmark, politiikkamatriisi, jäsennyslaite tai toistettava testi kertovat usein tarinan nopeammin kuin toinen abstrakti arkkitehtuurikeskustelu. Hyvät esineet ovat hämmästyttävän töykeitä. Ne keskeyttävät toiveajattelua.

Vastaesimerkki, joka säästää aikaa

Kallis virhe on vastata ratkaisulla, joka on suurempi kuin ensimmäinen hyödyllinen todiste. Tiimi näkee riskin tai viiveen ja tavoittaa välittömästi uuden alustan, uudelleenkirjoituksen, laajan refaktorin tai hankintaystävällisen kojelaudan, jonka nimi kuulostaa siltä kuin se tekee joogaa. Joskus tämä mittakaava on perusteltu. Hyvin usein se on tapa lykätä mittausta.

Parempi liike on pienempi ja terävämpi. Nimeä raja. Ota todisteet talteen. Muuta yksi tärkeä asia. Testaa samaa polkua uudelleen. Päätä sitten, kannattaako seuraava investointi olla suurempi. Tämä rytmi on vähemmän dramaattinen kuin muutosohjelma, mutta sillä on taipumus selviytyä kosketuksista budjetteihin, julkaisukalentereihin ja tuotantotapahtumiin.

Suosittelemamme toimitustapa

Luotettavimmassa mallissa on neljä vaihetta. Kerää ensin edustavia esineitä. Toiseksi, muuta nämä esineet yhdeksi vaikeaksi tekniseksi diagnoosiksi. Kolmanneksi lähetä yksi rajoitettu muutos tai prototyyppi. Neljänneksi, testaa uudelleen samalla mittauskehyksellä ja dokumentoi seuraava päätös selkeällä kielellä. Tässä työluokassa CMake-kalusteet, profilointivaljaat, pienet alkuperäiset reprot ja kääntäjä/ajonaikaiset muistiinpanot ovat yleensä arvokkaampia kuin toinen tapaus yleisestä suunnasta.

Selkeällä kielellä on väliä. Ostajan tulee pystyä lukemaan tulos ja ymmärtämään, mikä muuttui, mikä on edelleen riskialtista, mikä voi odottaa ja mitä seuraava askel ostaisi. Jos suositusta ei voida ajoittaa, testata tai määrittää omistajalle, se on silti liian koristeellinen. Koristeellinen tekninen kirjoittaminen on miellyttävää, mutta tuotantojärjestelmiä ei tunneta miellyttävyyden palkitsemisesta.

Kuinka arvioida, auttoiko tulos

Kohdassa The Art of Profiling C++ Applications tuloksen pitäisi parantaa ainakin yhtä kolmesta asiasta: toimitusnopeus, järjestelmän luottamus tai kaupallinen valmius. Jos se ei paranna mitään näistä, tiimi on saattanut oppia jotain, mutta ostaja ei ole vielä saanut hyödyllistä tulosta. Sillä erolla on merkitystä. Oppiminen on jaloa. Myös palkallisen toimeksiannon pitäisi siirtää järjestelmää.

Vahvin tulos voi olla kapeampi tiekartta, kieltäytyminen vaarallisen polun automatisoinnista, parempi raja mallin ympärille, puhtaampi natiiviintegraatio, mitattu todiste siitä, että uudelleenkirjoitusta ei vielä tarvita, tai lyhyt korjauslista, jonka johto voi todella rahoittaa. Vakava suunnittelu on sarja parempia päätöksiä, ei pukukilpailua työkaluista.

Miten SToFU suhtautuisi asiaan

SToFU käsittelee tätä ensin toimitusongelmana ja sitten teknologiaongelmana. Tuomme asiaan liittyvän suunnittelusyvyyden, mutta pitäisimme sitoutumisen ankkuroituna todisteisiin: polkuun, rajaan, riskiin, mittaukseen ja seuraavaan tekemisen arvoiseen muutokseen. Tarkoitus ei ole saada kovaa työtä kuulostamaan helpolta. Tarkoitus on tehdä seuraavasta vakavasta liikkeestä riittävän selkeä suoritettavaksi.

Sitä osaa ostajat yleensä arvostavat eniten. He voivat palkata mielipiteitä missä tahansa. He tarvitsevat tiimin, joka voi tarkastaa järjestelmän, nimetä todellisen rajoitteen, rakentaa tai vahvistaa oikean osion ja jättää taakseen artefakteja, jotka vähentävät sekaannusta puhelun päätyttyä. Meluisillä markkinoilla selkeys ei ole pehmeä taito. Se on infrastruktuuri.

Philip P.

Philip P. – CTO

Takaisin Blogeihin

Ota yhteyttä

Aloita keskustelu

Muutama selkeä viiva riittää. Kuvaile järjestelmää, painetta ja päätöstä, joka on estetty. Tai kirjoita suoraan osoitteeseen midgard@stofu.io.

01 Mitä järjestelmä tekee
02 Mikä nyt sattuu
03 Mikä päätös on estetty
04 Valinnainen: lokit, tiedot, jäljet, erot
0 / 10000
Tiedostoa ei ole valittu