Запускайте программы C++ быстрее

В следующей статье описываются простые (почти легкие) методы повышения производительности вашего приложения C++. Вы можете использовать все описанные методы одновременно, что значительно сократит конечное улучшение (время выполнения).

Первый способ связан с параллельным выполнением алгоритмов STL (с использованием доступных ядер ЦП). Параллельное выполнение было введено в C++17. В настоящее время C++20 предлагает 4 различных политики, которые вы можете быстро развернуть в своем коде. Вообще говоря, доступные политики определяют, как выполняется ваш алгоритм, и могут быть указаны следующим образом:

  1. политика последовательности — вам не разрешено запускать ваш алгоритм параллельно.
  2. параллельная политика — выполнение алгоритма выполняется одновременно на разных потоках.
  3. непоследовательная политика — как указано в документации, вы запускаете алгоритм в одиночных потоках, но ваш алгоритм векторизован «разделен», и определенные операции выполняются над разными элементами одновременно
  4. параллельная непоследовательная политика — как политика, указанная выше, однако определенные (разделенные элементы алгоритма) части вашего контейнера выполняются в разных потоках.

Есть две основные вещи, которые вы должны изменить в своем коде, см. пример:

#include <iostream>
#include <vector>
#include <execution> // this header has to be added
#include <algorithm>

int main()
{

    std::vector<double> v(1 << 30, 0.5);
    auto f = std::find(std::execution::par, v.begin(), v.end(), 0.6);
    // we use std::execution::par to execute algorithm in pararrel
    // in order to compare to sequential method run:
    // auto f = std::find(v.begin(), v.end(), 0.6);
}

Для параллельного выполнения кода вам необходимо использовать библиотеку TBB (Threading Building Blocks от Intel). Я рекомендую также книгу открытого доступа к современному руководству для всех программистов на C++, подробно объясняющему, как использовать TBB.
В нашем простом случае, когда нужно правильно скомпилировать наш код. Вы также должны установить TBB:

//install in Linux
sudo apt install libtbb-dev

Ваша программа должна быть скомпилирована следующим образом (я использую C++20 и gcc 11),

//you have to add flag: -ltbb
g++ parallel_computation.cpp --std=c++2a -ltbb -o pcomp

Вы можете проверить производительность и сравнить оба метода (в приведенном выше примере), запустив

time ./pcomp

На терминале вы увидите

real указывает фактическое время, затраченное на выполнение процесса от начала до конца (это сейчас для нас самое интересное), user — время, затраченное на добавление времени от всех ядер процессора. используется во время работы вашей программы, sys — время выделения (например, выделение памяти)

Как видите, при использовании параллельного алгоритма программа может работать примерно в 2,55 раза быстрее (в моем случае).

Другим способом сокращения времени выполнения может быть оптимизация при компиляции. Добавив флаг оптимизации -O1, -O2 или -O3, вы можете заставить компилятор оптимизировать ваш код до определенного уровня. Мы можем представить, что в данном случае оптимизация — это процесс перевода или сопоставления программного обеспечения более высокого уровня (C++) с кодом, который может выполняться на аппаратном обеспечении с максимально возможной скоростью. Обратите внимание, что оптимизация — это процесс, жадный до ресурсов (он требует ресурсов ЦП и памяти и увеличивает время компиляции).

Если вы запустите приведенный выше пример с уровнем оптимизации -O3

//you have to add flag: -ltbb
g++ parallel_computation.cpp --std=c++2a -ltbb -O3 -o pcomp

Ваше приложение может работать примерно в 2 раза быстрее

Спасибо за чтение.