Многопоточность
Функции многопоточности доступны через статический класс zephyr::utils::threads при подключении заголовочного файла zephyr/utils/threads.h. Проект включает две реализации многопоточности (STD и TBB), которые можно выбрать через [опцию CMake] THREADS_TYPE.
Управление потоками
Управление потоками глобальное: включение и выключение тредов касается всех функций, которые используют threads.
threads::on(); // Включить все доступные потоки
threads::on(N); // Включить N потоков
threads::off(); // Выключить многопоточность
Функции on/off могут быть использованы в произвольном месте программы. Для отладки определенных функций можно выключать треды до вызова функции и включать после.
Параллельный обход ячеек
Для сеток автоматически поддерживется многопоточность. Рассмотрим простой цикл по ячейкам сетки:
for (auto cell: mesh) {
// Операции над ячейкой
}
Аналогичный цикл в параллельном режиме:
mesh.for_each(
[](EuCell cell) {
// Операции над ячейкой
});
Если треды выключены, то оба варианта эквивалентны. Важно: при параллельном обходе ячеек нельзя менять значения в соседних ячейках!
Операции свёртки
Операции свёртки или reduce-функции, позволяют получить одно значение для набора данных. Поиск максимума, минимума, подсчет элементов или вычисление суммы являются операциями свёртки. Рассмотрим поиск минимального объема ячейки на сетке:
double min_volume = 1.0e300;
for (auto cell: mesh) {
min_volume = std::min(min_volume, cell.volume());
}
Параллельная версия того же алгоритма:
double min_volume = mesh.min(
[](EuCell cell) {
return cell.volume();
});
Здесь лямбда-функция возвращает объем для каждой ячейки, а функция mesh.min
находит минимальное значение в параллельном режиме. Аналогичным образом выполняются операции свёртки mesh.max(), mesh.sum().