SlideShare una empresa de Scribd logo
1 de 26
C++ User Group Russia, Ekaterinburg, 25.11.2016
Многопоточные вычисления, современный подход
Крутько Е.С.
НИЦ «Курчатовский институт»
e.s.krutko@gmail.com
Цель доклада
Современный стандарт C++ позволяет делать
многопоточные вычисления легко и удобно.
Если приложение или библиотека тратит меньше
времени на работу – это хорошо
Исходники тестов:
https://github.com/eskrut/multithread.git
2
Немного истории. Нативные потоки
3
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
void* someParallelTask(void *arg) {
int *preciousValue =
reinterpret_cast<int*>(arg);
*preciousValue = 1;
}
int main(int argc, char**argv) {
pthread_t thread;
int value, othreValue;
pthread_create(&thread,
nullptr,
someParallelTask,
&value);
someParallelTask(&othreValue);
pthread_join(thread, nullptr);
assert(value == othreValue);
return 0;
}
#include <stdlib.h>
#include <windows.h>
#include <assert.h>
DWORD WINAPI someParallelTask(void
*arg) {
int *preciousValue =
reinterpret_cast<int*>(arg);
*preciousValue = 1;
}
int main(int argc, char**argv) {
HANDLE thread;
int value, othreValue;
thread = CreateThread(
NULL,
0,
someParallelTask,
&value,
0,
NULL
);
someParallelTask(&othreValue);
WaitForSingleObject(thread,
INFINITE);
assert(value == othreValue);
Стандартные потоки. с++11
4
#include <stdlib.h>
#include <thread>
#include <assert.h>
void someParallelTask(int &value) {
value = 1;
}
int main(int argc, char**argv) {
std::thread thread;
int value, othreValue;
thread = std::thread(
someParallelTask,
std::ref(value));
someParallelTask(othreValue);
thread.join();
assert(value == othreValue);
return 0;
}
Threadpool. с++11
5
#include <stdlib.h>
#include <assert.h>
//git submodule add https://github.com/progschj/ThreadPool.git
#include "ThreadPool/ThreadPool.h"
int someExample();
int someExampleParallel();
int main(int argc, char**argv) {
someExample();
someExampleParallel();
return 0;
}
Threadpool. с++11
6
int someExample() {
int value1;
//code to evaluate value1
//may require significant amount of time
value1 = 3;
int value2;
//code to evaluate value2
//may require significant amount of time
value2 = 3;
//Now use some fancy algorythm using values
int result = value1 + value2;
assert(result == 6);
return result;
}
Threadpool. с++11
7
int someExampleParallel() {
ThreadPool pool(8);
auto futureValue1 = pool.enqueue([](){
int value1;
//code to evaluate value1
//may require significant amount of time
value1 = 3;
return value1;
});
auto futureValue2 = pool.enqueue([](){
int value2;
//code to evaluate value2
//may require significant amount of time
value2 = 3;
return value2;
});
//Now use some fancy algorythm using values
int result = futureValue1.get() + futureValue2.get();
assert(result == 6);
return result;
}
std::async. с++11
8
int someExampleParallel() {
auto futureValue1 = std::async([](){
int value1;
//code to evaluate value1
//may require significant amount of time
value1 = 3;
return value1;
});
auto futureValue2 = std::async([](){
int value2;
//code to evaluate value2
//may require significant amount of time
value2 = 3;
return value2;
});
//Now use some fancy algorythm using values
int result = futureValue1.get() + futureValue2.get();
assert(result == 6);
return result;
}
Пример из жизни
9
void PhotoSortModel::fill(const QString &path)
{
unsigned numRows = invisibleRootItem()->rowCount();
auto read = [this,path](int id, int start, int stop){
for(int row = start; row < stop; ++row) {
auto photo = photoItem(row);
readDown(photo, path);
QMetaObject::invokeMethod(this,
"partialDone",
Qt::DirectConnection,
Q_ARG(int, id),
Q_ARG(int, row-start));
}
return 0;
};
read(0, 0, numRows);
emit(loaded());
for(unsigned row = 0; row < numRows; ++row)
itemChanged(photoItem(row));
}
Пример из жизни
10
// read(0, 0, numRows);
doneMap_.clear();
doneMap_[-1] = numRows;
std::list<std::future<int>> futures;
unsigned numThreads = std::thread::hardware_concurrency();
for(unsigned ct = 0; ct < numThreads; ++ct) {
doneMap_[ct] = 0;
unsigned start = (ct*numRows)/numThreads;
unsigned stop = ((ct+1)*numRows)/numThreads;
if( (ct + 1) == numThreads && stop > numRows ) stop = numRows;
futures.push_back(std::async(read, ct, start, stop));
}
for(auto &f : futures)
f.get();
Последовательный код Параллельный
365.236 64.5399
Неприятности с параллельностью
11
int dataRaceTarget = 0;
int numCycles = 1000;
auto taskP = [](int volatile &dataRaceTarget,
int numCycles){
for(size_t ct = 0; ct < numCycles; ++ct)
dataRaceTarget++;
return 0;
};
auto taskM = [](int volatile &dataRaceTarget,
int numCycles){
for(size_t ct = 0; ct < numCycles; ++ct)
dataRaceTarget--;
return 0;
};
Неприятности с параллельностью
12
std::list<std::thread> threads;
for(size_t ct = 0; ct < std::thread::hardware_concurrency(); ++ct) {
if(ct % 2)
threads.push_back(std::thread(std::bind(
taskP,
std::ref(dataRaceTarget),
numCycles)));
else
threads.push_back(std::thread(std::bind(
taskM,
std::ref(dataRaceTarget),
numCycles)));
}
for(auto &t : threads) {
t.join();
}
std::cout << "result: " << dataRaceTarget << std::endl;
Поиск ошибок
Инстременты поиска несинхронного
доступа к памяти:
•valgring
•clang/gcc (linux only [пока])
13
valgring
valgrind --num-callers=1 --tool=helgrind ./datarace
==77960== Possible data race during read of size 4 at 0x10480810C by thread #3
==77960== Locks held: none
==77960== at 0x100002D2C: main::$_0::operator()(int volatile&, int) const
(datarace.cpp:15)
==77960==
==77960== This conflicts with a previous write of size 4 by thread #2
==77960== Locks held: none
==77960== at 0x100003634: main::$_1::operator()(int volatile&, int) const
(datarace.cpp:21)
==77960== Address 0x10480810c is on thread #1's stack
14
dataRaceTarget++;
Thread Sunitizer (clang/gcc)
option(TUNE_THREAD_SANITIZER "Perform thread error sanitizing" OFF)
if(TUNE_THREAD_SANITIZER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fPIC -fPIE" )
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread
-pie")
endif()
Thread T2 (tid=8175, running) created by main thread at:
#0 pthread_create <null>:0 (libtsan.so.0+0x000000047f23)
#1 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>)
<null>:0 (libstdc++.so.6+0x0000000b6a90)
#2 main /media/psf/Home/Google
Drive/work/doc/meetingCpp/2016Ekb/code/parallelTests/datarace/datarace.cpp:30
(datarace+0x000000005d8b)
15
threads.push_back(std::thread(std::bind(
taskP,
std::ref(dataRaceTarget),
numCycles)));
Параллельная [стандартная] библиотека / на примере gcc
16
const size_t length = 0.1 /*Gb*/
* 1024ull /*Mb*/
* 1024 /*Kb*/
* 1024 /*b*/
/ sizeof(size_t) /*count*/;
std::vector<size_t> vecOrigin;
vecOrigin.reserve(length);
for(size_t ct = 0; ct < length; ++ct)
vecOrigin.push_back(ct);
auto vecToSort = vecOrigin;
std::shuffle(vecToSort.begin(), vecToSort.end(),
std::default_random_engine(
hr_clock::now().time_since_epoch().count()
)
);
auto vecToSort2 = vecToSort;
Параллельная [стандартная] библиотека / на примере gcc
17
size_t max;
sw.start();
max = *std::max_element(
vecToSort.begin(),
vecToSort.end());
std::cout << sw.stop() << std::endl;
Параллельная [стандартная] библиотека / на примере gcc
18
size_t max;
sw.start();
max = *std::max_element(
vecToSort.begin(),
vecToSort.end());
std::cout << sw.stop() << std::endl;
size_t max2;
sw.start();
max2 = *std::__parallel::max_element(
vecToSort2.begin(),
vecToSort2.end());
std::cout << sw.stop() << std::endl;
if(max != length-1)
throw std::runtime_error("Cant evaluete max with sequential
max_element");
if(max2 != length-1)
throw std::runtime_error("Cant evaluete max with parallel
max_element");
Параллельная [стандартная] библиотека / на примере gcc
19
sw.start();
std::sort(vecToSort.begin(), vecToSort.end());
std::cout << sw.stop() << std::endl;
sw.start();
std::__parallel::sort(vecToSort2.begin(), vecToSort2.end());
std::cout << sw.stop() << std::endl;
Параллельная [стандартная] библиотека / на примере gcc
20
const size_t lengthData = 25000;
const size_t lengthVector = 6 /*Gb*/
* 1024ull /*Mb*/
* 1024 /*Kb*/
* 1024 /*b*/
/ sizeof(size_t) /*count*/
/ lengthData;
std::vector<std::vector<size_t>> dataBundle;
dataBundle.resize(lengthData, std::vector<size_t>(lengthVector,
0));
auto gen = std::default_random_engine(
hr_clock::now().time_since_epoch().count()
);
for(auto &vec : dataBundle) {
for(auto &value : vec) {
value = gen();
}
}
Параллельная [стандартная] библиотека / на примере gcc
21
std::vector<size_t> maxes(lengthData, 0);
sw.start();
std::for_each(
dataBundle.cbegin(),
dataBundle.cend(),
[&dataBundle, &maxes](const std::vector<size_t> &vec)
{
size_t index = &vec - dataBundle.data();
maxes[index] = *std::max_element(vec.begin(), vec.end());
}
);
std::cout << sw.stop() << std::endl;
std::vector<size_t> maxes2(lengthData, 0);
sw.start();
std::__parallel::for_each(dataBundle.cbegin(),
dataBundle.cend(),
[&dataBundle, &maxes2](const
std::vector<size_t> &vec)
{
size_t index = &vec - dataBundle.data();
maxes2[index] = *std::max_element(vec.begin(), vec.end());
}
);
std::cout << sw.stop() << std::endl;
Параллельная [стандартная] библиотека / на примере gcc
22
Результаты замены std на std::_parallel
std std::_parallel
max_element 0.015215 0.006585
sort 1.19395 0.264197
for_each 0.970016 0.356471
А если нужно большая гибкость? boost::thread
23
#include <stdlib.h>
#include "boost/thread.hpp"
#include <assert.h>
void someParallelTask() {
while(true) { //forewer cycle
boost::this_thread::disable_interruption di;
//alloc some resources to work
//do not interrupt me
boost::this_thread::restore_interruption ri(di);
//ok check if I should die (
boost::this_thread::interruption_point();
}
}
int main(int argc, char**argv) {
auto thread = boost::thread( someParallelTask );
//do some jod
//And now I do not want to wait thread
thread.interrupt();
thread.join();
return 0;
}
IMHO. Самая простая параллельность. OpenMP
24
int someExample() {
int value1;
//code to evaluate value1
//may require significant
amount of time
value1 = 3;
int value2;
//code to evaluate value2
//may require significant
amount of time
value2 = 3;
//Now use some fancy algorythm
using values
int result = value1 + value2;
assert(result == 6);
return result;
}
#include <omp.h>
int someExampleParallel() {
int value1;
int value2;
#pragma omp parallel sections
{
#pragma omp section
{
//code to evaluate value1
//may require significant
amount of time
value1 = 3;
}
#pragma omp section
{
//code to evaluate value2
//may require significant
amount of time
value2 = 3;
}
}//here we wait for all blocks
//Now use some fancy algorythm
using values
int result = value1 + value2;
assert(result == 6);
return result;
}
Итог
При достаточном уровне понимания сути алгоритма работы
программы с использованием современного C++ легко
внедрять параллельную обработку данных. И этим надо
пользоваться )
Я предпочитаю:
std::async и std::list<std::future<T>>
boost::thread (если нужен менеджер потоков)
OpenMP
25
Крутько Евгений
e.s.krutko@gmail.com
google.com/+ЕвгенийКрутько
26

Más contenido relacionado

La actualidad más candente

The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)
jeffz
 

La actualidad más candente (20)

Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
 
Дмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репортДмитрий Демчук. Кроссплатформенный краш-репорт
Дмитрий Демчук. Кроссплатформенный краш-репорт
 
TensorFlow XLA RPC
TensorFlow XLA RPCTensorFlow XLA RPC
TensorFlow XLA RPC
 
Basic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python ProgrammersBasic C++ 11/14 for Python Programmers
Basic C++ 11/14 for Python Programmers
 
Windbg랑 친해지기
Windbg랑 친해지기Windbg랑 친해지기
Windbg랑 친해지기
 
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
 
Joel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMDJoel Falcou, Boost.SIMD
Joel Falcou, Boost.SIMD
 
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
Bridge TensorFlow to run on Intel nGraph backends (v0.4)Bridge TensorFlow to run on Intel nGraph backends (v0.4)
Bridge TensorFlow to run on Intel nGraph backends (v0.4)
 
Bridge TensorFlow to run on Intel nGraph backends (v0.5)
Bridge TensorFlow to run on Intel nGraph backends (v0.5)Bridge TensorFlow to run on Intel nGraph backends (v0.5)
Bridge TensorFlow to run on Intel nGraph backends (v0.5)
 
C++ game development with oxygine
C++ game development with oxygineC++ game development with oxygine
C++ game development with oxygine
 
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты ...
 
Fuzzing: The New Unit Testing
Fuzzing: The New Unit TestingFuzzing: The New Unit Testing
Fuzzing: The New Unit Testing
 
TVM VTA (TSIM)
TVM VTA (TSIM) TVM VTA (TSIM)
TVM VTA (TSIM)
 
Welcome to Modern C++
Welcome to Modern C++Welcome to Modern C++
Welcome to Modern C++
 
Protocol handler in Gecko
Protocol handler in GeckoProtocol handler in Gecko
Protocol handler in Gecko
 
Pro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScriptPro typescript.ch03.Object Orientation in TypeScript
Pro typescript.ch03.Object Orientation in TypeScript
 
The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)The Evolution of Async-Programming on .NET Platform (TUP, Full)
The Evolution of Async-Programming on .NET Platform (TUP, Full)
 
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2  「エッジAIモダン計測制御の世界」オ...
Google Edge TPUで TensorFlow Liteを使った時に 何をやっているのかを妄想してみる 2 「エッジAIモダン計測制御の世界」オ...
 
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
Gor Nishanov,  C++ Coroutines – a negative overhead abstractionGor Nishanov,  C++ Coroutines – a negative overhead abstraction
Gor Nishanov, C++ Coroutines – a negative overhead abstraction
 

Destacado

Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Platonov Sergey
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
victor-yastrebov
 

Destacado (20)

Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на LinuxПавел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и JavascriptСергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
 
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
 
Григорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптерГригорий Демченко, Универсальный адаптер
Григорий Демченко, Универсальный адаптер
 
Parallel STL
Parallel STLParallel STL
Parallel STL
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Использование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработкиИспользование юнит-тестов для повышения качества разработки
Использование юнит-тестов для повышения качества разработки
 
Алексей Кутумов, C++ без исключений, часть 3
Алексей Кутумов,  C++ без исключений, часть 3Алексей Кутумов,  C++ без исключений, часть 3
Алексей Кутумов, C++ без исключений, часть 3
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Фитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в формеФитнес для вашего кода: как держать его в форме
Фитнес для вашего кода: как держать его в форме
 
C++ Core Guidelines
C++ Core Guidelines C++ Core Guidelines
C++ Core Guidelines
 
Quality assurance of large c++ projects
Quality assurance of large c++ projectsQuality assurance of large c++ projects
Quality assurance of large c++ projects
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Василий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексиейВасилий Сорокин, Простой REST сервер на Qt с рефлексией
Василий Сорокин, Простой REST сервер на Qt с рефлексией
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Антон Полухин. C++17
Антон Полухин. C++17Антон Полухин. C++17
Антон Полухин. C++17
 
Конверсия управляемых языков в неуправляемые
Конверсия управляемых языков в неуправляемыеКонверсия управляемых языков в неуправляемые
Конверсия управляемых языков в неуправляемые
 
C++ exceptions
C++ exceptionsC++ exceptions
C++ exceptions
 
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
 

Similar a Евгений Крутько, Многопоточные вычисления, современный подход.

Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
Yandex
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
Abed Bukhari
 
I want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdfI want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdf
bermanbeancolungak45
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Yandex
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
Teddy Hsiung
 
ISCA Final Presentaiton - Compilations
ISCA Final Presentaiton -  CompilationsISCA Final Presentaiton -  Compilations
ISCA Final Presentaiton - Compilations
HSA Foundation
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
aleks-f
 

Similar a Евгений Крутько, Многопоточные вычисления, современный подход. (20)

Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)Modern C++ Explained: Move Semantics (Feb 2018)
Modern C++ Explained: Move Semantics (Feb 2018)
 
Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++Степан Кольцов — Rust — лучше, чем C++
Степан Кольцов — Rust — лучше, чем C++
 
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
Story of static code analyzer development
Story of static code analyzer developmentStory of static code analyzer development
Story of static code analyzer development
 
I want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdfI want help in the following C++ programming task. Please do coding .pdf
I want help in the following C++ programming task. Please do coding .pdf
 
Bind me if you can
Bind me if you canBind me if you can
Bind me if you can
 
Groovy
GroovyGroovy
Groovy
 
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан КольцовRust: код может быть одновременно безопасным и быстрым, Степан Кольцов
Rust: код может быть одновременно безопасным и быстрым, Степан Кольцов
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
 
Write Python for Speed
Write Python for SpeedWrite Python for Speed
Write Python for Speed
 
ISCA Final Presentaiton - Compilations
ISCA Final Presentaiton -  CompilationsISCA Final Presentaiton -  Compilations
ISCA Final Presentaiton - Compilations
 
C++ AMP 실천 및 적용 전략
C++ AMP 실천 및 적용 전략 C++ AMP 실천 및 적용 전략
C++ AMP 실천 및 적용 전략
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
LSFMM 2019 BPF Observability
LSFMM 2019 BPF ObservabilityLSFMM 2019 BPF Observability
LSFMM 2019 BPF Observability
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! Look Ma, “update DB to HTML5 using C++”, no hands! 
Look Ma, “update DB to HTML5 using C++”, no hands! 
 
Modern C++ Concurrency API
Modern C++ Concurrency APIModern C++ Concurrency API
Modern C++ Concurrency API
 
C++ amp on linux
C++ amp on linuxC++ amp on linux
C++ amp on linux
 

Más de Platonov Sergey

HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
Platonov Sergey
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
Platonov Sergey
 

Más de Platonov Sergey (20)

Евгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализацияЕвгений Зуев, С++ в России: Стандарт языка и его реализация
Евгений Зуев, С++ в России: Стандарт языка и его реализация
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IIДмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
 
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках IДмитрий Кашицын, Вывод типов в динамических и не очень языках I
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
 
QML\Qt Quick на практике
QML\Qt Quick на практикеQML\Qt Quick на практике
QML\Qt Quick на практике
 
Визуализация автомобильных маршрутов
Визуализация автомобильных маршрутовВизуализация автомобильных маршрутов
Визуализация автомобильных маршрутов
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
HPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычисленийHPX: C++11 runtime система для параллельных и распределённых вычислений
HPX: C++11 runtime система для параллельных и распределённых вычислений
 
Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08Ranges calendar-novosibirsk-2015-08
Ranges calendar-novosibirsk-2015-08
 
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...Использование maven для сборки больших модульных c++ проектов на примере Odin...
Использование maven для сборки больших модульных c++ проектов на примере Odin...
 
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведенияДракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
 
One definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим житьOne definition rule - что это такое, и как с этим жить
One definition rule - что это такое, и как с этим жить
 
DI в C++ тонкости и нюансы
DI в C++ тонкости и нюансыDI в C++ тонкости и нюансы
DI в C++ тонкости и нюансы
 
Аскетичная разработка браузера
Аскетичная разработка браузераАскетичная разработка браузера
Аскетичная разработка браузера
 
Concepts lite
Concepts liteConcepts lite
Concepts lite
 
Денис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система QtДенис Кормалев Метаобъектная система Qt
Денис Кормалев Метаобъектная система Qt
 
Максим Хижинский Lock-free maps
Максим Хижинский Lock-free mapsМаксим Хижинский Lock-free maps
Максим Хижинский Lock-free maps
 
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
Владислав Шаклеин. Смешивание управляемого и неуправляемого C++ кода в Micros...
 
High quality library from scratch
High quality library from scratchHigh quality library from scratch
High quality library from scratch
 
С++ without new and delete
С++ without new and deleteС++ without new and delete
С++ without new and delete
 
Categories for the Working C++ Programmer
Categories for the Working C++ ProgrammerCategories for the Working C++ Programmer
Categories for the Working C++ Programmer
 

Último

Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 

Último (20)

%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
What Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the SituationWhat Goes Wrong with Language Definitions and How to Improve the Situation
What Goes Wrong with Language Definitions and How to Improve the Situation
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 

Евгений Крутько, Многопоточные вычисления, современный подход.

  • 1. C++ User Group Russia, Ekaterinburg, 25.11.2016 Многопоточные вычисления, современный подход Крутько Е.С. НИЦ «Курчатовский институт» e.s.krutko@gmail.com
  • 2. Цель доклада Современный стандарт C++ позволяет делать многопоточные вычисления легко и удобно. Если приложение или библиотека тратит меньше времени на работу – это хорошо Исходники тестов: https://github.com/eskrut/multithread.git 2
  • 3. Немного истории. Нативные потоки 3 #include <stdlib.h> #include <pthread.h> #include <assert.h> void* someParallelTask(void *arg) { int *preciousValue = reinterpret_cast<int*>(arg); *preciousValue = 1; } int main(int argc, char**argv) { pthread_t thread; int value, othreValue; pthread_create(&thread, nullptr, someParallelTask, &value); someParallelTask(&othreValue); pthread_join(thread, nullptr); assert(value == othreValue); return 0; } #include <stdlib.h> #include <windows.h> #include <assert.h> DWORD WINAPI someParallelTask(void *arg) { int *preciousValue = reinterpret_cast<int*>(arg); *preciousValue = 1; } int main(int argc, char**argv) { HANDLE thread; int value, othreValue; thread = CreateThread( NULL, 0, someParallelTask, &value, 0, NULL ); someParallelTask(&othreValue); WaitForSingleObject(thread, INFINITE); assert(value == othreValue);
  • 4. Стандартные потоки. с++11 4 #include <stdlib.h> #include <thread> #include <assert.h> void someParallelTask(int &value) { value = 1; } int main(int argc, char**argv) { std::thread thread; int value, othreValue; thread = std::thread( someParallelTask, std::ref(value)); someParallelTask(othreValue); thread.join(); assert(value == othreValue); return 0; }
  • 5. Threadpool. с++11 5 #include <stdlib.h> #include <assert.h> //git submodule add https://github.com/progschj/ThreadPool.git #include "ThreadPool/ThreadPool.h" int someExample(); int someExampleParallel(); int main(int argc, char**argv) { someExample(); someExampleParallel(); return 0; }
  • 6. Threadpool. с++11 6 int someExample() { int value1; //code to evaluate value1 //may require significant amount of time value1 = 3; int value2; //code to evaluate value2 //may require significant amount of time value2 = 3; //Now use some fancy algorythm using values int result = value1 + value2; assert(result == 6); return result; }
  • 7. Threadpool. с++11 7 int someExampleParallel() { ThreadPool pool(8); auto futureValue1 = pool.enqueue([](){ int value1; //code to evaluate value1 //may require significant amount of time value1 = 3; return value1; }); auto futureValue2 = pool.enqueue([](){ int value2; //code to evaluate value2 //may require significant amount of time value2 = 3; return value2; }); //Now use some fancy algorythm using values int result = futureValue1.get() + futureValue2.get(); assert(result == 6); return result; }
  • 8. std::async. с++11 8 int someExampleParallel() { auto futureValue1 = std::async([](){ int value1; //code to evaluate value1 //may require significant amount of time value1 = 3; return value1; }); auto futureValue2 = std::async([](){ int value2; //code to evaluate value2 //may require significant amount of time value2 = 3; return value2; }); //Now use some fancy algorythm using values int result = futureValue1.get() + futureValue2.get(); assert(result == 6); return result; }
  • 9. Пример из жизни 9 void PhotoSortModel::fill(const QString &path) { unsigned numRows = invisibleRootItem()->rowCount(); auto read = [this,path](int id, int start, int stop){ for(int row = start; row < stop; ++row) { auto photo = photoItem(row); readDown(photo, path); QMetaObject::invokeMethod(this, "partialDone", Qt::DirectConnection, Q_ARG(int, id), Q_ARG(int, row-start)); } return 0; }; read(0, 0, numRows); emit(loaded()); for(unsigned row = 0; row < numRows; ++row) itemChanged(photoItem(row)); }
  • 10. Пример из жизни 10 // read(0, 0, numRows); doneMap_.clear(); doneMap_[-1] = numRows; std::list<std::future<int>> futures; unsigned numThreads = std::thread::hardware_concurrency(); for(unsigned ct = 0; ct < numThreads; ++ct) { doneMap_[ct] = 0; unsigned start = (ct*numRows)/numThreads; unsigned stop = ((ct+1)*numRows)/numThreads; if( (ct + 1) == numThreads && stop > numRows ) stop = numRows; futures.push_back(std::async(read, ct, start, stop)); } for(auto &f : futures) f.get(); Последовательный код Параллельный 365.236 64.5399
  • 11. Неприятности с параллельностью 11 int dataRaceTarget = 0; int numCycles = 1000; auto taskP = [](int volatile &dataRaceTarget, int numCycles){ for(size_t ct = 0; ct < numCycles; ++ct) dataRaceTarget++; return 0; }; auto taskM = [](int volatile &dataRaceTarget, int numCycles){ for(size_t ct = 0; ct < numCycles; ++ct) dataRaceTarget--; return 0; };
  • 12. Неприятности с параллельностью 12 std::list<std::thread> threads; for(size_t ct = 0; ct < std::thread::hardware_concurrency(); ++ct) { if(ct % 2) threads.push_back(std::thread(std::bind( taskP, std::ref(dataRaceTarget), numCycles))); else threads.push_back(std::thread(std::bind( taskM, std::ref(dataRaceTarget), numCycles))); } for(auto &t : threads) { t.join(); } std::cout << "result: " << dataRaceTarget << std::endl;
  • 13. Поиск ошибок Инстременты поиска несинхронного доступа к памяти: •valgring •clang/gcc (linux only [пока]) 13
  • 14. valgring valgrind --num-callers=1 --tool=helgrind ./datarace ==77960== Possible data race during read of size 4 at 0x10480810C by thread #3 ==77960== Locks held: none ==77960== at 0x100002D2C: main::$_0::operator()(int volatile&, int) const (datarace.cpp:15) ==77960== ==77960== This conflicts with a previous write of size 4 by thread #2 ==77960== Locks held: none ==77960== at 0x100003634: main::$_1::operator()(int volatile&, int) const (datarace.cpp:21) ==77960== Address 0x10480810c is on thread #1's stack 14 dataRaceTarget++;
  • 15. Thread Sunitizer (clang/gcc) option(TUNE_THREAD_SANITIZER "Perform thread error sanitizing" OFF) if(TUNE_THREAD_SANITIZER) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fPIC -fPIE" ) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread -pie") endif() Thread T2 (tid=8175, running) created by main thread at: #0 pthread_create <null>:0 (libtsan.so.0+0x000000047f23) #1 std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) <null>:0 (libstdc++.so.6+0x0000000b6a90) #2 main /media/psf/Home/Google Drive/work/doc/meetingCpp/2016Ekb/code/parallelTests/datarace/datarace.cpp:30 (datarace+0x000000005d8b) 15 threads.push_back(std::thread(std::bind( taskP, std::ref(dataRaceTarget), numCycles)));
  • 16. Параллельная [стандартная] библиотека / на примере gcc 16 const size_t length = 0.1 /*Gb*/ * 1024ull /*Mb*/ * 1024 /*Kb*/ * 1024 /*b*/ / sizeof(size_t) /*count*/; std::vector<size_t> vecOrigin; vecOrigin.reserve(length); for(size_t ct = 0; ct < length; ++ct) vecOrigin.push_back(ct); auto vecToSort = vecOrigin; std::shuffle(vecToSort.begin(), vecToSort.end(), std::default_random_engine( hr_clock::now().time_since_epoch().count() ) ); auto vecToSort2 = vecToSort;
  • 17. Параллельная [стандартная] библиотека / на примере gcc 17 size_t max; sw.start(); max = *std::max_element( vecToSort.begin(), vecToSort.end()); std::cout << sw.stop() << std::endl;
  • 18. Параллельная [стандартная] библиотека / на примере gcc 18 size_t max; sw.start(); max = *std::max_element( vecToSort.begin(), vecToSort.end()); std::cout << sw.stop() << std::endl; size_t max2; sw.start(); max2 = *std::__parallel::max_element( vecToSort2.begin(), vecToSort2.end()); std::cout << sw.stop() << std::endl; if(max != length-1) throw std::runtime_error("Cant evaluete max with sequential max_element"); if(max2 != length-1) throw std::runtime_error("Cant evaluete max with parallel max_element");
  • 19. Параллельная [стандартная] библиотека / на примере gcc 19 sw.start(); std::sort(vecToSort.begin(), vecToSort.end()); std::cout << sw.stop() << std::endl; sw.start(); std::__parallel::sort(vecToSort2.begin(), vecToSort2.end()); std::cout << sw.stop() << std::endl;
  • 20. Параллельная [стандартная] библиотека / на примере gcc 20 const size_t lengthData = 25000; const size_t lengthVector = 6 /*Gb*/ * 1024ull /*Mb*/ * 1024 /*Kb*/ * 1024 /*b*/ / sizeof(size_t) /*count*/ / lengthData; std::vector<std::vector<size_t>> dataBundle; dataBundle.resize(lengthData, std::vector<size_t>(lengthVector, 0)); auto gen = std::default_random_engine( hr_clock::now().time_since_epoch().count() ); for(auto &vec : dataBundle) { for(auto &value : vec) { value = gen(); } }
  • 21. Параллельная [стандартная] библиотека / на примере gcc 21 std::vector<size_t> maxes(lengthData, 0); sw.start(); std::for_each( dataBundle.cbegin(), dataBundle.cend(), [&dataBundle, &maxes](const std::vector<size_t> &vec) { size_t index = &vec - dataBundle.data(); maxes[index] = *std::max_element(vec.begin(), vec.end()); } ); std::cout << sw.stop() << std::endl; std::vector<size_t> maxes2(lengthData, 0); sw.start(); std::__parallel::for_each(dataBundle.cbegin(), dataBundle.cend(), [&dataBundle, &maxes2](const std::vector<size_t> &vec) { size_t index = &vec - dataBundle.data(); maxes2[index] = *std::max_element(vec.begin(), vec.end()); } ); std::cout << sw.stop() << std::endl;
  • 22. Параллельная [стандартная] библиотека / на примере gcc 22 Результаты замены std на std::_parallel std std::_parallel max_element 0.015215 0.006585 sort 1.19395 0.264197 for_each 0.970016 0.356471
  • 23. А если нужно большая гибкость? boost::thread 23 #include <stdlib.h> #include "boost/thread.hpp" #include <assert.h> void someParallelTask() { while(true) { //forewer cycle boost::this_thread::disable_interruption di; //alloc some resources to work //do not interrupt me boost::this_thread::restore_interruption ri(di); //ok check if I should die ( boost::this_thread::interruption_point(); } } int main(int argc, char**argv) { auto thread = boost::thread( someParallelTask ); //do some jod //And now I do not want to wait thread thread.interrupt(); thread.join(); return 0; }
  • 24. IMHO. Самая простая параллельность. OpenMP 24 int someExample() { int value1; //code to evaluate value1 //may require significant amount of time value1 = 3; int value2; //code to evaluate value2 //may require significant amount of time value2 = 3; //Now use some fancy algorythm using values int result = value1 + value2; assert(result == 6); return result; } #include <omp.h> int someExampleParallel() { int value1; int value2; #pragma omp parallel sections { #pragma omp section { //code to evaluate value1 //may require significant amount of time value1 = 3; } #pragma omp section { //code to evaluate value2 //may require significant amount of time value2 = 3; } }//here we wait for all blocks //Now use some fancy algorythm using values int result = value1 + value2; assert(result == 6); return result; }
  • 25. Итог При достаточном уровне понимания сути алгоритма работы программы с использованием современного C++ легко внедрять параллельную обработку данных. И этим надо пользоваться ) Я предпочитаю: std::async и std::list<std::future<T>> boost::thread (если нужен менеджер потоков) OpenMP 25