Показаны сообщения с ярлыком std. Показать все сообщения
Показаны сообщения с ярлыком std. Показать все сообщения

воскресенье, 20 июля 2025 г.

Новые возможности C++20: std::execution::par


Поспрашивал тут у ChatGPT что нового у мире C++ и тут завезли очень классную штуку: std::execution::par. Никак не напрягаясь дополнительно, мы просто делаем тот же самый sort, но благодаря дополнительному параметру он сам распарралеливает все на несколько ядер/потоков. Тот же ЧатЖПТ сам мне дал код примера, который отлично скомпилировался в моей Visual Studio 2022:

#include <execution> // параллельные политики #include <algorithm> // std::sort #include <vector> #include <random> #include <chrono> #include <iostream> int main() { const size_t N = 5'000'000; // Количество элементов // --- 1. Генерация случайных данных --- std::vector<int> data(N); std::mt19937 rng(42); std::uniform_int_distribution<int> dist(0, 1'000'000); std::generate(data.begin(), data.end(), [&] { return dist(rng); }); // Создаём копии для честного сравнения auto data_seq = data; auto data_par = data; // --- 2. Последовательная сортировка --- auto t1 = std::chrono::high_resolution_clock::now(); std::sort(data_seq.begin(), data_seq.end()); auto t2 = std::chrono::high_resolution_clock::now(); std::cout << "std::sort (seq): " << std::chrono::duration<double>(t2 - t1).count() << " s\n"; // --- 3. Параллельная сортировка --- auto t3 = std::chrono::high_resolution_clock::now(); std::sort(std::execution::par, data_par.begin(), data_par.end()); auto t4 = std::chrono::high_resolution_clock::now(); std::cout << "std::sort (par): " << std::chrono::duration<double>(t4 - t3).count() << " s\n"; // --- 4. Проверка корректности --- std::cout << "First elements: seq=" << data_seq[0] << ", par=" << data_par[0] << "\n"; return 0; }

Результаты такие:

std::sort (seq): 0.371002 s
std::sort (par): 0.0917933 s

Запущено на AMD Ryzen 7 7730U (8c/16t).

Нуу, очень неплохо: добавлением всего одного параметра увеличиваем скорость в 4 раза!

Чтобы это работало, надо не забыть оказать версию C++ в Visual Studio:




пятница, 20 апреля 2018 г.

Поиск функцией std::find_if по ассоциативному спику std::map / Searching by std::find_if on std::map

Иногда надо перебрать все элементы ассоциативного списка и можно это сделать традиционно, с помощью цикла for.
Но есть более изящное решение с использованием возможностей C++11. Допустим у нас есть ассоциативный список типа  std::unordered_map<int, MyType>.
Вот как это можно сделать:

// very clear lambda statement
auto pred = [sVal](const std::pair<int, MyType>& x) { return x.second.val == sVal; }; 
const auto it = std::find_if(myMap.begin(), myMap.end(), pred);

Но есть один недостаток: надо явно указывать тип элемента контейнера, который мы перебираем, в лямбда-выражении. Но можно сделать так, чтобы компилятор сам определал это:

// does the same, but looks much smarter ^_^
auto pred = [sVal](const decltype(myMap.begin())::value_type& x) { return x.second.val == sVal; }; 
const auto it = std::find_if(myMap.begin(), myMap.end(), pred);

Получилось боле громоздко, но зато более универсально.