OpenMP开销计算
OpenMP overhead calculation
给定n个线程,是否有一种方法可以计算在OpenMP中实现特定指令所需的开销(例如周期#)。
例如,给定
下面的代码 #pragma omp parallel
{
#pragma omp for
for( int i=0 ; i < m ; i++ )
a[i] = b[i] + c[i];
}
我能计算出创建这些线程需要多少开销吗?
我认为测量开销的方法是对串行和并行版本进行计时,然后看看并行版本与你的线程数量的"理想"运行时间有多远。
例如,如果您的串行版本需要10秒,并且您在4核上有4个线程,那么理想的运行时间是2.5秒。如果您的OpenMP版本需要4秒,那么您的"开销"是1.5秒。我把开销用引号括起来,因为其中一些开销是线程创建和内存共享(实际的线程开销),而其中一些开销只是代码的非并行部分。我试着用阿姆达尔定律来思考这个问题。
作为演示,这里有两个示例。它们不度量线程创建开销,但它们可能显示预期的改进和实现的改进之间的差异。虽然mystic是对的,唯一真正衡量它的方法是计时,但即使是像for
循环这样微不足道的例子也不一定受内存限制。OpenMP做了很多我们看不到的工作。
系列(speedtest.cpp)
#include <iostream>
int main(int argc, char** argv) {
const int SIZE = 100000000;
int* a = new int[SIZE];
int* b = new int[SIZE];
int* c = new int[SIZE];
for(int i = 0; i < SIZE; i++) {
a[i] = b[i] * c[i] * 2;
}
std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;
for(int i = 0; i < SIZE; i++) {
a[i] = b[i] + c[i] + 1;
}
std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;
delete[] a;
delete[] b;
delete[] c;
return 0;
}
平行(omp_speedtest.cpp)
#include <omp.h>
#include <iostream>
int main(int argc, char** argv) {
const int SIZE = 100000000;
int* a = new int[SIZE];
int* b = new int[SIZE];
int* c = new int[SIZE];
std::cout << "There are " << omp_get_num_procs() << " procs." << std::endl;
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < SIZE; i++) {
a[i] = b[i] * c[i];
}
}
std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < SIZE; i++) {
a[i] = b[i] + c[i] + 1;
}
}
std::cout << "a[" << (SIZE-1) << "]=" << a[SIZE-1] << std::endl;
delete[] a;
delete[] b;
delete[] c;
return 0;
}
所以我用
编译了这些g++ -O3 -o speedtest.exe speedtest.cpp
g++ -fopenmp -O3 -o omp_speedtest.exe omp_speedtest.cpp
当我运行它们时
$ time ./speedtest.exe
a[99999999]=0
a[99999999]=1
real 0m1.379s
user 0m0.015s
sys 0m0.000s
$ time ./omp_speedtest.exe
There are 4 procs.
a[99999999]=0
a[99999999]=1
real 0m0.854s
user 0m0.015s
sys 0m0.015s
可以。请看EPCC基准。虽然这段代码有点老,但它测量了OpenMP结构的各种开销,包括omp parallel for
和omp critical
。
基本方法是非常简单和直接的。您在没有任何OpenMP的情况下测量基线串行时间,并且只包含您想要测量的OpenMP pragma。然后,减去经过的时间。这正是EPCC基准测量开销的方法。查看源代码,如' synchbench .c'。
请注意,开销表示为时间,而不是周期数。我还尝试测量周期,但是OpenMP并行结构的开销可能包括由于同步而阻塞的时间。因此,# of周期可能不能反映OpenMP的实际开销。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 递归函数计算序列中的平方和(并输出过程)
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的字符计数代码计算错误.为什么
- 在计算中使用二的幂有多有利可图
- 实现无开销push_back的最佳方法是什么
- 如何计算文件中的"columns"数?
- 计算排序向量的向量中唯一值的计数
- 如何使用 std::累积在 C++ 中计算总和立方体
- 使用Qt C++计算类似Git的SHA1哈希
- OpenCV C++.快速计算混淆矩阵
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数据类型的范围,例如int
- 类似枚举的计算常量
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 计算缩放多边形的比例,得到给定的多边形面积
- OpenMP开销计算
- 计算在C (gcc/g++)中打包的开销