傻瓜式搭建网站,专业做网站流程,wordpress源码阅读,网站图片上传不上去怎么办某些并行循环不需要执行所有迭代。 例如#xff0c;搜索值的算法可以在找到值后终止。 OpenMP 不提供中断并行循环的机制。 但是#xff0c;可以使用布尔值或标志来启用循环迭代#xff0c;以指示已找到解决方案。 并发运行时提供允许一个任务取消其他尚未启动的任务的功能。…某些并行循环不需要执行所有迭代。 例如搜索值的算法可以在找到值后终止。 OpenMP 不提供中断并行循环的机制。 但是可以使用布尔值或标志来启用循环迭代以指示已找到解决方案。 并发运行时提供允许一个任务取消其他尚未启动的任务的功能。
此示例演示如何将一个不需要运行所有迭代的 OpenMP parallelfor 循环转换为使用并发运行时取消机制。
示例
此示例同时使用 OpenMP 和并发运行时来实现 std::any_of 算法的并行版本。 此示例的 OpenMP 版本使用标志来协调所有满足条件的并行循环迭代。 使用并发运行时的版本使用 concurrency::structured_task_group::cancel 方法在满足条件时停止整个操作。
// concrt-omp-parallel-any-of.cpp
// compile with: /EHsc /openmp
#include ppl.h
#include array
#include random
#include iostreamusing namespace concurrency;
using namespace std;// Uses OpenMP to determine whether a condition exists in
// the specified range of elements.
template class InIt, class Predicate
bool omp_parallel_any_of(InIt first, InIt last, const Predicate pr)
{typedef typename std::iterator_traitsInIt::value_type item_type;// A flag that indicates that the condition exists.bool found false;#pragma omp parallel forfor (int i 0; i static_castint(last-first); i){if (!found){item_type cur *(first i);// If the element satisfies the condition, set the flag to // cancel the operation.if (pr(cur)) {found true;}}}return found;
}// Uses the Concurrency Runtime to determine whether a condition exists in
// the specified range of elements.
template class InIt, class Predicate
bool concrt_parallel_any_of(InIt first, InIt last, const Predicate pr)
{typedef typename std::iterator_traitsInIt::value_type item_type;structured_task_group tasks;// Create a predicate function that cancels the task group when// an element satisfies the condition.auto for_each_predicate [pr, tasks](const item_type cur) {if (pr(cur)) {tasks.cancel();}};// Create a task that calls the predicate function in parallel on each// element in the range.auto task make_task([]() {parallel_for_each(first, last, for_each_predicate);});// The condition is satisfied if the task group is in the cancelled state.return tasks.run_and_wait(task) canceled;
}int wmain()
{// The length of the array.const size_t size 100000;// Create an array and initialize it with random values.arrayint, size a; generate(begin(a), end(a), mt19937(42));// Search for a value in the array by using OpenMP and the Concurrency Runtime.const int what 9114046;auto predicate [what](int n) - bool { return (n what);};wcout LUsing OpenMP... endl;if (omp_parallel_any_of(begin(a), end(a), predicate)){wcout what L is in the array. endl;}else{wcout what L is not in the array. endl;}wcout LUsing the Concurrency Runtime... endl;if (concrt_parallel_any_of(begin(a), end(a), predicate)){wcout what L is in the array. endl;}else{wcout what L is not in the array. endl;}
}
本示例生成以下输出。
Using OpenMP...
9114046 is in the array.
Using the Concurrency Runtime...
9114046 is in the array.
在使用 OpenMP 的版本中将执行循环的所有迭代即使设置了标志。 此外如果任务具有任何子任务则标志还必须可供这些子任务用来传达取消信息。 在并发运行时中当任务组被取消时运行时会取消整个工作树包括子任务。 concurrency::parallel_for_each 算法使用任务来执行工作。 因此当循环的一次迭代取消根任务时也会取消整个计算树。 取消工作树后运行时不会启动新任务。 但是运行时允许已经开始的任务完成。 因此对于 parallel_for_each 算法活动循环迭代可以清理其资源。
在此示例的两个版本中如果数组包含要搜索的值的多个副本则多个循环迭代可以同时设置结果并取消整个操作。 如果问题要求在满足条件时只有一个任务执行工作则可以使用同步基元如关键部分。
编译代码
复制示例代码并将它粘贴到 Visual Studio 项目中或粘贴到名为 concrt-omp-parallel-any-of.cpp 的文件中再在 Visual Studio 命令提示符窗口中运行以下命令。
cl.exe /EHsc /openmp concrt-omp-parallel-any-of.cpp