Следующий пример выполняет два алгоритма поиска параллельно и выбирает первый алгоритм для завершения. В этом примере определяется тип, содержащий числовые идентификаторы employee и зарплату для сотрудника. Функция find_employee находит первого сотрудника, имеющего предоставленный идентификатор или указанную зарплату. Функция find_employee также обрабатывает ситуацию, когда у сотрудника нет предоставленного идентификатора или заработной платы. Функция wmain создает массив объектов и ищет несколько идентификаторов и значений employee заработной платы.
В примере используется choice объект для выбора из следующих случаев:
Сотрудник, имеющий предоставленный идентификатор, существует.
Существует сотрудник, имеющий предоставленную зарплату.
Нет сотрудника, имеющего предоставленный идентификатор или зарплату.
В первых двух случаях в примере используется параллелизм::single_assignment для хранения идентификатора и другого single_assignment объекта для хранения заработной платы. В примере используется join объект для третьего случая. Объект join состоит из двух дополнительных single_assignment объектов, один для случая, когда ни один сотрудник, имеющий предоставленный идентификатор, существует, и один для случая, когда ни один сотрудник, имеющий предоставленную зарплату, не существует. Объект join отправляет сообщение, когда каждый из его членов получает сообщение. В этом примере объект отправляет сообщение, join если у сотрудника, имеющего предоставленный идентификатор или зарплату.
В примере используется объект параллелизма::structured_task_group для параллельного запуска обоих алгоритмов поиска. Каждая задача поиска записывается в один из single_assignment объектов, чтобы указать, существует ли данный сотрудник. В примере используется функция параллелизма::receive для получения индекса первого буфера, содержащего сообщение и switch блок для печати результата.
C++
// find-employee.cpp// compile with: /EHsc#include<agents.h>#include<ppl.h>#include<array>#include<iostream>#include<random>usingnamespace concurrency;
usingnamespacestd;
// Contains information about an employee.structemployee
{int id;
float salary;
};
// Finds the first employee that has the provided id or salary.template <typename T>
voidfind_employee(const T& employees, int id, float salary){
// Holds the salary for the employee with the provided id.
single_assignment<float> find_id_result;
// Holds the id for the employee with the provided salary.
single_assignment<int> find_salary_result;
// Holds a message if no employee with the provided id exists.
single_assignment<bool> id_not_found;
// Holds a message if no employee with the provided salary exists.
single_assignment<bool> salary_not_found;
// Create a join object for the "not found" buffers.// This join object sends a message when both its members holds a message // (in other words, no employee with the provided id or salary exists).auto not_found = make_join(&id_not_found, &salary_not_found);
// Create a choice object to select among the following cases:// 1. An employee with the provided id exists.// 2. An employee with the provided salary exists.// 3. No employee with the provided id or salary exists.auto selector = make_choice(&find_id_result, &find_salary_result, ¬_found);
// Create a task that searches for the employee with the provided id.auto search_id_task = make_task([&]{
auto result = find_if(begin(employees), end(employees),
[&](const employee& e) { return e.id == id; });
if (result != end(employees))
{
// The id was found, send the salary to the result buffer.
send(find_id_result, result->salary);
}
else
{
// The id was not found.
send(id_not_found, true);
}
});
// Create a task that searches for the employee with the provided salary.auto search_salary_task = make_task([&]{
auto result = find_if(begin(employees), end(employees),
[&](const employee& e) { return e.salary == salary; });
if (result != end(employees))
{
// The salary was found, send the id to the result buffer.
send(find_salary_result, result->id);
}
else
{
// The salary was not found.
send(salary_not_found, true);
}
});
// Use a structured_task_group object to run both tasks.
structured_task_group tasks;
tasks.run(search_id_task);
tasks.run(search_salary_task);
wcout.setf(ios::fixed, ios::fixed);
wcout.precision(2);
// Receive the first object that holds a message and print a message.int index = receive(selector);
switch (index)
{
case0:
wcout << L"Employee with id " << id << L" has salary "
<< receive(find_id_result);
break;
case1:
wcout << L"Employee with salary " << salary << L" has id "
<< receive(find_salary_result);
break;
case2:
wcout << L"No employee has id " << id << L" or salary " << salary;
break;
default:
__assume(0);
}
wcout << L'.' << endl;
// Cancel any active tasks and wait for the task group to finish.
tasks.cancel();
tasks.wait();
}
int wmain()
{
// Create an array of employees and assign each one a
// random id and salary.
array<employee, 10000> employees;
mt19937 gen(15);
const float base_salary = 25000.0f;
for (int i = 0; i < employees.size(); ++i)
{
employees[i].id = gen()%100000;
float bonus = static_cast<float>(gen()%5000);
employees[i].salary = base_salary + bonus;
}
// Search for several id and salary values.
find_employee(employees, 14758, 30210.00);
find_employee(employees, 340, 29150.00);
find_employee(employees, 61935, 29255.90);
find_employee(employees, 899, 31223.00);
}
В этом примере формируются следующие данные:
Output
Employee with id 14758 has salary 27780.00.
Employee with salary 29150.00 has id 84345.
Employee with id 61935 has salary 29905.00.
No employee has id 899 or salary 31223.00.
В этом примере функция параллелизма::make_choice вспомогательной функции используется для создания choice объектов и вспомогательной функции параллелизма::make_join вспомогательной функции для создания join объектов.
Компиляция кода
Скопируйте пример кода и вставьте его в проект Visual Studio или вставьте его в файл с именем find-employee.cpp , а затем выполните следующую команду в окне командной строки Visual Studio.
Azure HPC — это специально разработанная облачная возможность для рабочей нагрузки HPC и ИИ, использующая современные отраслевые процессоры и обмен данными по сети InfiniBand для обеспечения максимальной производительности, масштабируемости и ценности приложений. Azure HPC позволяет реализовывать инновации, повышать продуктивность и развивать гибкость бизнеса за счет высокодоступного набора технологий HPC и ИИ с возможностью их динамического распределения в соответствии с изменением коммерческих и техническ