对OpenMP中静态调度开销的影响
Influence on the static scheduling overhead in OpenMP
我考虑了哪些因素会影响OpenMP中的静态调度开销。在我看来,它受到以下因素的影响:
- CPU性能
- OpenMP运行库的具体实现
- 线程数
但我是否遗漏了其他因素?也许是任务的规模…?
进一步:开销是否线性依赖于迭代次数?在这种情况下,我希望拥有静态调度和4核,开销随着4* I迭代线性增加。到目前为止正确吗?
编辑:我只对静态调度开销本身感兴趣。我不是在谈论线程启动开销、同步开销和临界区开销。
您需要将OpenMP创建线程组/线程池的开销与每个线程在for循环中操作单独的迭代器集的开销分开。
静态调度很容易手工实现(这有时非常有用)。让我们考虑我认为最重要的两个静态调度schedule(static)
和schedule(static,1)
,然后我们可以将其与schedule(dynamic,chunk)
进行比较。
#pragma omp parallel for schedule(static)
for(int i=0; i<N; i++) foo(i);
等于(但不一定等于)
#pragma omp parallel
{
int start = omp_get_thread_num()*N/omp_get_num_threads();
int finish = (omp_get_thread_num()+1)*N/omp_get_num_threads();
for(int i=start; i<finish; i++) foo(i);
}
和
#pragma omp parallel for schedule(static,1)
for(int i=0; i<N; i++) foo(i);
等价于
#pragma omp parallel
{
int ithread = omp_get_thread_num();
int nthreads = omp_get_num_threads();
for(int i=ithread; i<N; i+=nthreads) foo(i);
}
从这里你可以看到,实现静态调度非常简单,因此开销可以忽略不计。
另一方面,如果你想实现schedule(dynamic)
(这是相同的schedule(dynamic,1)
)的手,它更复杂:
int cnt = 0;
#pragma omp parallel
for(int i=0;;) {
#pragma omp atomic capture
i = cnt++;
if(i>=N) break;
foo(i);
}
这需要OpenMP>=3.1。如果您想在OpenMP 2.0(用于MSVC)中这样做,您需要使用像这样的关键字
int cnt = 0;
#pragma omp parallel
for(int i=0;;) {
#pragma omp critical
i = cnt++;
if(i>=N) break;
foo(i);
}
下面是等价于schedule(dynamic,chunk)
(我没有使用原子访问对其进行优化):
int cnt = 0;
int chunk = 5;
#pragma omp parallel
{
int start, finish;
do {
#pragma omp critical
{
start = cnt;
finish = cnt+chunk < N ? cnt+chunk : N;
cnt += chunk;
}
for(int i=start; i<finish; i++) foo(i);
} while(finish<N);
}
显然,使用原子访问将导致更多的开销。这也说明了为什么为schedule(dynamic,chunk)
使用更大的块可以减少开销。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 实现无开销push_back的最佳方法是什么
- 为什么擦除方法会影响结束方法
- 内联如何影响模块接口中的成员函数
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 别名模板的专业化 C++11 中没有开销的最佳替代方案
- C++标准是否允许<double>在没有开销的情况下实现 std::可选
- 在容量内调整矢量大小时的性能影响
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 类型擦除的std::function与虚拟函数调用的开销
- 未达到的情况会影响开关外壳性能
- 一组值的零开销下标运算符
- C++ 特征库:引用的性能开销<>
- 循环仅对第一行正常工作.其他行不受 for 的影响
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 模板如何影响C++中隐式声明的规则?
- C++对开销较少的容器使用多个过滤器
- 在编译时评估函数开销的通用方法
- 命名空间信息会影响C++的可读性
- 对OpenMP中静态调度开销的影响