19 июн. 2009 г.

Пример функции parallel_reduce

В предыдущей статье об Intel Threading Building Blocks рассказывалось о преимуществах этой библиотеки, а также был рассмотрен пример алгоритма parallel_for. Рассмотрим пример использования алгоритма parallel_reduce, который отличается от функции parallel_for тем, что позволяет объединить частичные результаты, полученные в парралельных потоках.

Прежде всего, нужно подключить необходимые заголовочные файлы:

#include <stdio.h>

#include <tbb/blocked_range.h>

#include <tbb/parallel_reduce.h>

#include <tbb/task_scheduler_init.h>

* This source code was highlighted with Source Code Highlighter.

Здесь stdio.h используется для включения функции printf (вывод на экран), blocked_range.h для использования класса blocked_range (блочный диапазон), parallel_reduce.h для включения соответствующего алгоритма, а task_scheduler_inti.h — для включения планировщика задач.

Как было сказано ранее, стандартные алгоритмы Intel TBB — parallel_for, parallel_reduce — используют концепцию класса-задачи. В примере ниже показан подобный класс для решения задачи нахождения значения константы Пи (пример навеян конкурсом Интела, а также самостоятельной работой моего студента). Суть нахождения числа заключается в вычислении площади криволинейной трапеции, которая примерно описана большим количеством прямоугольников. Чем больше прямоугольников, тем точнее значение, но тем и больше времени требуется для вычисления. Иллюстрацию к этой задаче можно посмотреть на сайте «Вольфрам-Альфа».

// Класс-задача, отвечает за подсчет значения пи на заданном диапазаоне


class PiCalculation {

private:   

// Количество шагов в интервале, влияет на точность   

long num_steps;   // Ширина шага   double step; public:   // Частичное значение пи   double pi;   // Вычислить частичное значение пи на заданном диапазоне   void operator () (const tbb::blocked_range<long> &r)   {     double sum = 0.0;     long end = r.end();     for (int i = r.begin(); i != end; i++)     {       double x = (i + 0.5) * step;       sum += 4.0/(1.0 + x * x);     }     pi += sum * step;   }   // Объеденить частичные результаты   void join(PiCalculation &p)   {     pi += p.pi;   }   // Разделяющий конструктор   PiCalculation(PiCalculation &p, tbb::split)   {     pi = 0.0;     num_steps = p.num_steps;     step = p.step;   }      // Конструктор   PiCalculation(long steps)   {     pi = 0.0;     num_steps = steps;     step = 1./(double)num_steps;   } };
* This source code was highlighted with Source Code Highlighter.

Важными в этом классе есть следующие два метода: operator () и join.

Метод void operator () (const blocked_range &r) вычисляет частичный результат в интервале [r.begin, r.end). Библиотека Intel TBB и класс blocked_range заботятся о том, чтобы рекурсивно разбить исходное пространство итераций и «скармливать» небольшими порциями методу operator (). Результат накапливается в переменной pi, которая частная для потока. Дается гарантия, что operator () для одного класса будет вызван только из одного потока, поэтому ошибки типа «гонки за данными» (data races, race conditions) исключены.

Метод void join (PiCalculation &p) суммирует частные результаты различных потоков. Здесь проявляется важное отличие библиотеки Intel TBB от библиотек OpenMP и MPI, в которых количество операций для объединения частичных результатов (reduction, редуцирование) ограничено. Intel TBB позволяет реализовать произвольные функции объединения результатов в теле метода join.

Рассмотрим запуск алгоритма parallel_reduce.

int main() {   // Инициализация библиотеки Intel TBB   tbb::task_scheduler_init init;   // Количество итераций   const long steps = 100000000;   // Создание объекта-задачи по вычислению пи   // Передается параметр: количество итераций   PiCalculation pi(steps);   // Запуск алгоритма parallel_reduce над диапазоном [0, steps)   tbb::parallel_reduce(tbb::blocked_range<long>(0, steps, 1000000), pi);   printf ("Pi is %3.20f\n", pi.pi);   return 0; } * This source code was highlighted with Source Code Highlighter.

Для этого необходимо выполнить следующие шаги: создать объект планировщика задач Intel TBB, создать объект задачи PiCalculation, и вызвать функцию parallel_reduce. Здесь функция принимает два параметра. Первый — это класс диапазона. В нашем случае мы указывает количество итераций [0, steps), т. е. при вычислении интеграла от 0 до 1 будет использовано steps = 100 000 000 шагов. Второй параметр — это ссылка на объект задачи, в котором после возвращения из функции parallel_reduce будет содержаться значение пи.

Комментариев нет:

Отправить комментарий

Темы

2012 (2) амазон (1) анпакинг (1) артемий лебедев (4) атн (1) аудио (1) аэропорт (1) безопасность (3) бизнес (1) билайн (1) блог (2) будущее (2) видео (11) википедия (5) вымысел (16) гагарин (1) герман (1) гитхаб (1) гугл (3) дед мороз (1) декабрь (1) демотиватор (2) дети (2) дизайн (13) диссертация (2) документация (1) друзья (5) евпатория (1) евро-2012 (1) жадность (1) заяц (1) идея (1) имейл (1) инстаграм (1) интервью (5) интересное (20) интерфейс (13) история (7) как_выжить (4) календарь (1) капитализм (1) картина (1) кмб (6) книга (6) коллекция (4) компилятор (2) конкурс (5) космос (1) лаборатория (1) либералы (1) лингво (1) лузер (6) макаренко (2) макдональдс (2) математика (1) медиапорт (1) ментор (1) металлика (1) металлист (2) метро (7) микрософт (6) миргород (1) москва (2) музыка (3) наркомания (1) новости (17) образование (3) оптимизация (5) основы (14) открытки (3) ошибка (11) памятник (1) патриотизм (3) плагиат (1) плата (1) погода (3) поиск (1) политика (2) полтава (2) праздник (1) программирование (15) прошлое (2) путешествия (8) рейтинг (1) рендер (1) рисунок (2) русские (1) русский язык (1) сайт (4) санкт-петербург (1) сапр (7) сеть (1) си++ (1) синтез (1) системси (1) скриншот (40) социализм (1) соцопрос (3) спектрум (2) спорт (2) срач (2) статистика (1) такси (1) тбб (3) твитер (9) тимошенко (1) украина (5) униан (1) фан (30) фокус (1) фото (39) фотошоп (1) фурсенко (1) футбол (2) хабр (1) харьков (21) хнурэ (19) хобби (4) цитата (2) чехия (1) школа (1) эпл (1) эхостар (1) юмор (1) яндекс (1) clang (2) doxygen (1) english (3) ios (1) llvm (1) msdn (1) outlook (1) PHP (1) stackoverflow (1)

Поиск

Читатели