考虑到:
void saxpy_worksharing(float* x, float* y, float a, int N) {
#pragma omp parallel for
for (int i = 0; i < N; i++) {
y[i] = y[i]+a*x[i];
}
}
And
void saxpy_tasks(float* x, float* y, float a, int N) {
#pragma omp parallel
{
for (int i = 0; i < N; i++) {
#pragma omp task
{
y[i] = y[i]+a*x[i];
}
}
}
使用任务和 omp 并行指令有什么区别?为什么我们可以用任务来编写递归算法,例如合并排序,但不能用工作共享来编写?
我建议您看一下劳伦斯利弗莫尔国家实验室的 OpenMP 教程,可用here https://hpc-tutorials.llnl.gov/openmp/.
你的具体例子应该是not使用 OpenMP 任务来实现。第二个代码创建N
乘以线程任务数(因为除了缺少的代码之外,代码中还有错误}
;我稍后会回来讨论),并且每个任务仅执行非常简单的计算。正如您在我的回答中看到的那样,任务的开销将是巨大的这个问题 https://stackoverflow.com/questions/13034718/producer-consumer-using-openmp-tasks。此外,第二个代码在概念上是错误的。由于没有工作共享指令,所有线程都将执行循环的所有迭代,而不是N
tasks, N
创建的线程任务数的倍数。应通过以下方式之一重写:
单任务生产者 - 常见模式,NUMA 不友好:
void saxpy_tasks(float* x, float* y, float a, int N) {
#pragma omp parallel
{
#pragma omp single
{
for (int i = 0; i < N; i++)
#pragma omp task
{
y[i] = y[i]+a*x[i];
}
}
}
}
The single
指令将使循环仅在单个线程内运行。所有其他线程都会跳过它并在结束时遇到隐式屏障single
构造。由于屏障包含隐式任务调度点,等待线程将在任务可用时立即开始处理任务。
并行任务生成器 - 对 NUMA 更友好:
void saxpy_tasks(float* x, float* y, float a, int N) {
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < N; i++)
#pragma omp task
{
y[i] = y[i]+a*x[i];
}
}
}
在这种情况下,任务创建循环将在线程之间共享。
如果你不知道什么是 NUMA,请忽略有关 NUMA 友好性的评论。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)