C++ Academy · Oppitunti

Koodin suorituskyvyn mittaaminen

Vertaa suorituskykyä chronolla

Oppitunti 3/413 vaihetta

Koodin suorituskyvyn mittaaminen on ilmainen C++ Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu C++ Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Miksi tehdä suorituskykymittauksia?

Koodin suoritusajan mittaaminen auttaa löytämään pullonkaulat ja varmistamaan optimoinnit. <chrono> tarjoaa siirrettävän ja tyyppiturvallisen tavan mitata aikaa.

  • Mitatkaa ennen optimointia.
  • Käyttäkää vakaata kelloa luotettavien aikavälien mittaamiseen.
#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    auto end = steady_clock::now();
    std::cout << "Timed a block: " << ((end - start).count() >= 0) << '\n';
    return 0;
}

Perusmalli

Suorituskykymittauksen perusmalli on aina sama: tallentakaa now() ennen suoritusta, suorittakaa työ, tallentakaa now() sen jälkeen ja vähentäkää arvot toisistaan.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 100000; ++i) sum += i;
    auto end = steady_clock::now();
    std::cout << "Sum: " << sum << ", elapsed >= 0: " << ((end - start).count() >= 0) << '\n';
    return 0;
}

Yksikön valitseminen

Valitkaa työmäärään sopiva yksikkö. Käyttäkää nopeissa silmukoissa yksiköitä microseconds tai nanoseconds ja suuremmissa tehtävissä yksikköä milliseconds.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 500000; ++i) sum += i;
    auto end = steady_clock::now();
    auto us = duration_cast<microseconds>(end - start);
    std::cout << "Result: " << sum << ", us non-negative: " << (us.count() >= 0) << '\n';
    return 0;
}

Ajan mittaaminen liukuluvuilla

Kun tarvitsette ihmiselle luettavia sekunteja murto-osineen, käyttäkää tyyppiä duration<double>, jotta alle sekunnin tarkkuus säilyy.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto start = steady_clock::now();
    long sum = 0;
    for (int i = 0; i < 200000; ++i) sum += i % 7;
    auto end = steady_clock::now();
    duration<double> secs = end - start;
    std::cout << "Computed " << sum << ", seconds >= 0: " << (secs.count() >= 0) << '\n';
    return 0;
}

Uudelleenkäytettävä ajastin

Sijoittakaa perusmalli pieneen apufunktioon, jotta voitte mitata minkä tahansa kutsuttavan olion suoritusajan siististi ilman toistuvaa koodia.

#include <iostream>
#include <chrono>

long long timeWork() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    long acc = 0;
    for (int i = 0; i < 100000; ++i) acc += i;
    auto e = steady_clock::now();
    return duration_cast<microseconds>(e - s).count();
}

int main() {
    std::cout << "Microseconds non-negative: " << (timeWork() >= 0) << '\n';
    return 0;
}

Kuolleen koodin poiston estäminen

Kääntäjät saattavat poistaa työn, jonka tulosta ei käytetä, mikä pilaa suorituskykymittaukset. Käyttäkää aina tulosta, esimerkiksi tulostamalla se tai kartuttamalla näkyvää muuttujaa.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    volatile long sink = 0;
    for (int i = 0; i < 100000; ++i) sink += i;
    auto e = steady_clock::now();
    std::cout << "Sink used: " << (sink > 0) << ", elapsed >= 0: " << ((e - s).count() >= 0) << '\n';
    return 0;
}

Lämmittelyajot

Ensimmäinen ajo voi olla välimuistien ja laiskan alustuksen vuoksi hitaampi. Tehkää ennen mittaamista lämmittelyajo, jotta tulokset ovat tasaisempia.

#include <iostream>
#include <chrono>

long work() {
    long a = 0;
    for (int i = 0; i < 50000; ++i) a += i;
    return a;
}

int main() {
    using namespace std::chrono;
    work();
    auto s = steady_clock::now();
    long r = work();
    auto e = steady_clock::now();
    std::cout << r << " measured, ok: " << ((e - s).count() >= 0) << '\n';
    return 0;
}

Useiden ajojen keskiarvo

Yksittäinen mittaus on altis vaihtelulle. Suorittakaa työ monta kertaa, laskekaa kuluneet kestot yhteen ja jakakaa summa vakaan keskiarvon saamiseksi.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    long long total = 0;
    const int runs = 5;
    for (int r = 0; r < runs; ++r) {
        auto s = steady_clock::now();
        long acc = 0;
        for (int i = 0; i < 100000; ++i) acc += i;
        auto e = steady_clock::now();
        total += duration_cast<microseconds>(e - s).count();
    }
    std::cout << "Average us non-negative: " << ((total / runs) >= 0) << '\n';
    return 0;
}

Kahden lähestymistavan vertailu

Vertailumittaus on parhaimmillaan toteutuksia verrattaessa. Mitatkaa jokainen niistä samalla tavalla ja verratkaa saatuja kestoja.

#include <iostream>
#include <chrono>
#include <vector>

int main() {
    using namespace std::chrono;
    std::vector<int> v;
    auto s1 = steady_clock::now();
    for (int i = 0; i < 10000; ++i) v.push_back(i);
    auto e1 = steady_clock::now();
    v.clear();
    v.reserve(10000);
    auto s2 = steady_clock::now();
    for (int i = 0; i < 10000; ++i) v.push_back(i);
    auto e2 = steady_clock::now();
    std::cout << "Both timed: " << (((e1 - s1).count() >= 0) && ((e2 - s2).count() >= 0)) << '\n';
    return 0;
}

Varokaa resoluutiota

Jos mitattava työ kestää vähemmän kuin kellon yksi tikki, tulokseksi voi tulla nolla. Suorittakaa työ silmukassa riittävän monta kertaa, jotta kellon resoluutio ylittyy.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    int x = 1 + 1;
    auto e = steady_clock::now();
    auto ns = duration_cast<nanoseconds>(e - s).count();
    std::cout << "x=" << x << ", tiny work may read low: " << (ns >= 0) << '\n';
    return 0;
}

Tulosten raportointi

Muun­takaa lopullinen kesto helposti luettavaan yksikköön ja tulostakaa se. Pitäkää käytetty tulos näkyvissä, jotta optimoija ei voi poistaa työtä.

#include <iostream>
#include <chrono>

int main() {
    using namespace std::chrono;
    auto s = steady_clock::now();
    long acc = 0;
    for (int i = 0; i < 300000; ++i) acc += (i * 3) % 11;
    auto e = steady_clock::now();
    auto ms = duration_cast<milliseconds>(e - s).count();
    std::cout << "acc=" << acc << ", ms >= 0: " << (ms >= 0) << '\n';
    return 0;
}

Pikatarkistus

Testatkaa, miten hyvin ymmärrätte suorituskyvyn vertailumittauksen sudenkuopat.

Kertaus

Opitte mittaamaan koodin suorituskykyä <chrono>-kirjaston avulla:

  • ottakaa steady_clock::now() talteen ennen suoritusta ja sen jälkeen ja vähentäkää ajat toisistaan
  • valitkaa sopiva yksikkö duration_cast-funktion avulla
  • suorittakaa lämmitys, laskekaa useiden suorituskertojen keskiarvo ja käyttäkää tuloksia, jotta kuolleen koodin poisto ei vaikuta tulokseen
  • huomioikaa kellon resoluutio pienissä työkuormissa

Seuraavaksi tutustutte C++20:n kalenteri- ja aikavyöhyketyyppeihin.

Aloita maksutta

Opi C++ tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
51
Oppitunnit
203

Usein kysytyt kysymykset

Onko oppitunti ”Koodin suorituskyvyn mittaaminen” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa C++ Academy-oppimispolun 3 oppituntia, myös oppitunnin “Koodin suorituskyvyn mittaaminen”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. C++ Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Koodin suorituskyvyn mittaaminen”?

Vertaa suorituskykyä chronolla Harjoittelet C++ Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C++ Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C++ Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Koodin suorituskyvyn mittaaminen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C++ Academy-oppitunnilla?

Kyllä. Jokainen C++ Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Kestot ja kellot
  2. Aikapisteet
  3. Koodin suorituskyvyn mittaaminen
  4. Kalenteri ja aikavyöhykkeet
← Takaisin: C++ Academy