注:本文主要内容摘自笔者所著的《多核计算与程序设计》一书,略有修改,后续还会继续发布系列文章,如有需要,可以考虑将一下地址加入到您的浏览器收藏夹中:http://software.intel.com/zh-cn/blogs/category/multicore/。
从前面的CNestTaskScheduler的使用方法中可以发现,采用嵌套任务调度,可以很方便地将一个大区间拆分成更多的小区间,将各个拆分后的区间放入分布式队列中,然后各个线程再从分布式队列中取出相应的区间进行处理。
对于一个for循环来说,通常处理的都是一个区间,因此也可以使用任务调度的方式将其拆分成更小的区间进行并行化执行。下面就利用嵌套任务调度的方法来实现一个Parall_For功能。
1. 区间的描述:CRange类
要实现对区间的分拆功能,使用一个类CRange来描述区间。在实际情况中,区间通常可以由两个整数表示区间开始和结束位置,也可以由两个迭代器变量来表示区间开始和结束位置。不过CRange是一个抽象接口类,它并不定义区间的开始和结束位置,区间的开始和结束位置由继承它的类去定义。CRange类用C++定义如下:
class CRange {
protected:
CNestTaskScheduler *m_pTaskScheduler;
public:
CRange(){};
CRange(CNestTaskScheduler *p);
void SetTaskScheduler(CNestTaskScheduler *p);
CNestTaskScheduler *GetTaskScheduler();
virtual CRange * Split() = 0;
};
在CRange类中,最重要的一个接口是Split()接口,这个接口负责将一个区间拆分成两个区间,一个区间继续存放在原来的CRange对象中,另外一个区间存放在返回的CRange对象中。如果返回值为NULL,表明原来的区间不需要进行分拆。
CRange类本身是一个接口类,用它主要是作为Parallel_For()函数的接口函数,Parallel_For()函数的原型如下:
void Parallel_For(CRange *pRange );
由于Split()是一个纯虚函数,因此传给Parallel_For()函数的参数必须是一个继续了CRange类的派生类的实例。
2. 对CRange对象的处理过程
对于每个CRange对象,Parallel_For()中需要对它进行处理,处理是通过任务调度器中的任务入口函数来处理的,处理过程如下图所示:
图4 CRange对象的处理过程
上面的处理过程可以用C++代码实现如下:
/** CRange的任务处理入口函数
@param void *pArg - 实际为一个CRange指针
@return unsigned int WINAPI - CAPI_FAILED表示失败,CAPI_SUCCESS表示成功
*/
unsigned int WINAPI RangeProcessTask(void *pArg)
{
CRange *pRange = (CRange *)pArg;
if ( pRange == NULL )
{
return CAPI_FAILED;
}
CRange *pNewRange = pRange->Split();
if ( pNewRange == NULL )
{
delete pRange;
return CAPI_SUCCESS;
}
CNestTaskScheduler *pTaskSched = pRange->GetTaskScheduler();
pNewRange->SetTaskScheduler(pTaskSched);
TASK t1, t2;
t1.pArg = (void *)pRange;
t1.func = RangeProcessTask;
t2.pArg = (void *)pNewRange;
t2.func = RangeProcessTask;
pTaskSched->SpawnLocalTask(t1);
pTaskSched->SpawnTask(t2);
return CAPI_SUCCESS;
}
3. Parall_For的处理流程
有了上面的RangeProcessTask()函数后,就可以用它作为嵌套任务调度器的任务入口函数,以实现Parallel_For功能。
在Parallel_For()中,主要实现对CRange对象的任务调度处理,需要将参数pRange作为根任务传入到任务调度器中进行处理。
Parallel_For()的处理过程如下:
图5 Parallel_For的处理过程
Parallel_For()的代码如下:
/** 并行for循的处理函数
将一个CRange进行并行处理
@param CRange *pRange - CRange指针
@return void - 无
*/
void Parallel_For(CRange *pRange )
{
CNestTaskScheduler *p = new CNestTaskScheduler;
TASK task;
task.func = RangeProcessTask;
task.pArg = pRange;
pRange->SetTaskScheduler(p);
p->BeginRootThread(task);
delete p;
}
分享到:
相关推荐
"Scheduling Multi-Periodic Mixed-Criticality DAGs on Multi-Core Architectures.pdf"则深入到混合关键性的多周期任务调度问题。在多核架构上,处理具有不同优先级和截止日期的任务图(DAG)是一个挑战。该文档...
3. **动态任务调度**:OpenMP支持动态生成任务,允许程序在运行时创建新的并行任务,增强了灵活性。 4. **循环并行化**:`#pragma omp for`用于并行化循环,自动分配循环迭代给不同的线程。 5. **同步和通信**:`#...
用户只需将原来的“for”循环替换为“parfor”,MATLAB会自动处理任务调度和数据分发。 2. **GPU并行**:对于计算密集型任务,如图像处理和数值计算,MATLAB可以利用NVIDIA的CUDA技术在GPU上进行并行计算。通过...
- **动态调度**:支持不同的调度策略,可以根据运行时的实际负载动态分配工作量,从而实现更好的负载均衡。 - **数据管理**:提供了对私有变量、共享变量以及线程本地数据的支持,帮助开发者更好地管理数据访问和...
- 任务并行:TBB的任务调度器可以动态地分配任务,无需预知任务间的依赖关系。 - 流式编程:TBB的flow graph API允许创建数据和控制流网络,方便处理异步和顺序依赖。 - 动态资源管理:TBB能够根据系统负载自动...
总而言之,《Task Scheduling for Multi-Core and Parallel Architectures》这本书填补了当前关于多核和并行架构下任务调度技术研究的空白,对于理解并行计算领域的最新进展以及应对未来挑战具有重要意义。
### CUDA for Engineers: An Introduction to High-Performance Parallel Computing #### 关键知识点概述 1. **CUDA简介** - CUDA(Compute Unified Device Architecture)是NVIDIA公司开发的一种并行计算平台和...
Federated Scheduling of Parallel Real-Time Tasks on Multiprocessors》和《Semi-Federated Scheduling of Mixed-Criticality System for Sporadic DAG Tasks》等文献,我们可以深入研究半联合调度的具体实现细节...
这些算法在内部使用任务调度和并行循环来实现,能有效利用多核处理器的优势。 4. **数据并行**:TBB的`tbb::parallel_vector`和`tbb::concurrent_vector`提供了并行访问数组的能力。前者在多线程环境下安全地进行...
负载均衡策略可能包括动态任务调度和工作窃取等。 - **并行算法设计**:将串行算法转化为并行算法是并行计算的关键。这可能涉及如何划分任务、如何合并结果以及如何减少通信开销。 - **错误处理与调试**:并行计算...
- `schedule`命令子句配合`for`循环并行化任务调度语句,可以将循环内的计算任务分配给多个线程并行执行,适合解决关联性任务的调度问题。 #### 实验示例(方法一) 下面是一个具体的实验代码示例,展示了如何使用...
为了调试和排查这类问题,可以利用`System.Diagnostics.Debugger`类的断点和条件断点功能,或者使用`System.Threading.Tasks.TaskScheduler.UnobservedTaskException`事件来捕获未观察到的任务异常。`...
* 算法模块:提供一些通用的并行算法,如 parallel_for、parallel_while、parallel_reduce。 * 容器模块:提供对常见容器的线程安全版本实现,如 hashmap、vector、queue。 * 内存分配模块:提供一些内存分配相关的...
5. 资源管理:并行计算需要高效的资源调度来管理多个工作器,包括启动、监控工作器状态以及在计算完成后释放资源。 6. 并行环境配置:用户可以通过配置工具设置并行环境,比如指定集群、工作器数量、资源名称等。 ...
这个文件很可能是实现不同调度策略的C代码示例,展示了如何使用`#pragma omp parallel for schedule`指令来控制循环的调度方式。例如,`schedule(static, chunk_size)`会使用静态调度,其中`chunk_size`表示每个...
TBB通过提供高级别的抽象,如并行_for循环(parallel_for)、并行区域(parallel_region)和任务调度器(task scheduler),使得并行化编程变得更加简单和高效。 **parallel_for** 是TBB中的核心组件之一,它允许...
TBB的任务调度器是其核心组件之一,它负责任务的分配和执行。任务可以被创建并提交到一个任务队列,调度器会根据系统资源动态地决定何时何地运行这些任务,确保负载均衡和性能最大化。 **3. 并行容器和并行算法** ...
通过配置MATLAB集群调度器,用户可以提交任务到集群,利用大量计算节点的计算资源,适合处理极为复杂的计算问题。 除了上述并行计算模式,MATLAB并行计算工具箱还提供了一些其他功能: - **数据并行**:使用`...
这些扩展包括更多的并行算法、任务调度器、监控工具等,帮助开发者更好地控制并行执行的行为。 **8. 并行调试与性能分析** 为了便于调试和性能分析,`.NET Framework`提供了一些工具,如Visual Studio的并发可视化...
接下来可以深入学习更多高级特性和优化技巧,如数据依赖性处理、任务调度策略等,进一步提升应用的并行效率和性能表现。 #### 法律信息 Intel® Threading Building Blocks受版权和其他法律保护,使用时应遵守相应...