Поделиться через


Практическое руководство. Использование преобразователя в конвейере данных

Этот раздел содержит простой пример, который показывает, как использовать concurrency::transformer класса данных конвейера.Более полный пример, в котором для параллельной обработки изображения используется конвейер данных, см. в разделе Пошаговое руководство. Создание сети обработки изображений.

Конвейеризация данных — это общий шаблон в параллельном программировании.Конвейер данных состоит из ряда этапов, каждый из которых выполняет работу и передает результаты этой работы на следующий этап.Класс transformer является ключевым компонентом конвейеров данных, так как он получает входное значение, выполняет работу с этим значением и производит результат, который затем используется другим компонентом.

Пример

В этом примере для выполнения ряда преобразований с начальным входным значением используется следующий конвейер данных.

  1. На первом этапе вычисляется его абсолютное значение.

  2. На втором этапе вычисляется квадратный корень из введенного значения.

  3. На третьем этапе вычисляется квадрат введенного значения.

  4. На четвертом этапе из полученного значения вычитается введенное.

  5. На пятом этапе окончательный результат записывается в буфер сообщений.

Наконец, результат конвейера выводится на консоль.

// data-pipeline.cpp
// compile with: /EHsc
#include <agents.h>
#include <math.h>
#include <iostream>

using namespace concurrency;
using namespace std;

int wmain()
{
   // Computes the absolute value of its input.
   transformer<int, int> t0([](int n) {
      return abs(n);
   });

   // Computes the square root of its input.
   transformer<int, double> t1([](int n) {
      return sqrt(static_cast<double>(n));
   });

   // Computes the square its input.
   transformer<double, int> t2([](double n) {
      return static_cast<int>(n * n);
   });

   // Negates its input.
   transformer<int, int> t3([](int n) {
      return -n;
   });

   // Holds the result of the pipeline computation.
   single_assignment<int> result;

   // Link together each stage of the pipeline.
   // t0 -> t1 -> t2 -> t3 -> result
   t0.link_target(&t1);
   t1.link_target(&t2);
   t2.link_target(&t3);
   t3.link_target(&result);

   // Propagate a message through the pipeline.
   send(t0, -42);

   // Print the result to the console.
   wcout << L"The result is " << receive(result) << L'.' << endl;
}

В этом примере получается следующий результат:

The result is -42.

Часто этап конвейера данных выводит значение, отличающееся по типу от введенного.В этом примере второй этап принимает значение типа int в качестве входных данных и выдает на выходе квадратный корень из этого значения (значение double).

ПримечаниеПримечание

Конвейер данных в этом пример носит иллюстративный характер.Так как каждая операция преобразования выполняет небольшую работу, дополнительная нагрузка, необходимая для передачи сообщений, может не компенсироваться преимуществами использования конвейера данных.

Компиляция кода

Скопируйте код и вставьте его в проект Visual Studio или вставьте его в файл с именем данные pipeline.cpp и запустите следующую команду в окне командной строки Visual Studio.

cl.exe /EHsc data-pipeline.cpp

См. также

Задачи

Пошаговое руководство. Создание сети обработки изображений

Основные понятия

Библиотека асинхронных агентов

Асинхронные блоки сообщений