给定n个线程,有没有办法可以计算在OpenMP中实现特定指令所需的开销量(例如周期数)。
例如,给出以下代码
#pragma omp parallel
{
#pragma omp for
for( int i=0 ; i < m ; i++ )
a[i] = b[i] + c[i];
}
我能否以某种方式计算创建这些线程需要多少开销?
答案 0 :(得分:4)
我认为衡量开销的方法是对串行和并行版本进行计时,然后看看并行版本距离其线程数的“理想”运行时间有多远。
因此,例如,如果您的串行版本需要10秒钟而且4个内核上有4个线程,那么理想的运行时间为2.5秒。如果您的OpenMP版本需要4秒,那么您的“开销”是1.5秒。我把开销放在引号中,因为其中一些将是线程创建和内存共享(实际的线程开销),其中一些只是代码的非平行部分。我试图用Amdahl's Law来思考。
为了演示,这里有两个例子。它们不会测量线程创建开销,但它们可能会显示预期和实现的改进之间的差异。虽然Mystical是正确的,唯一真正的衡量方法是计时,但即使像for
循环这样的小例子也不一定是内存限制的。 OpenMP做了很多我们没有看到的工作。
#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;
}
#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
答案 1 :(得分:4)
是的,你可以。请看EPCC benchmark。虽然此代码有点旧,但它会测量OpenMP构造的各种开销,包括omp parallel for
和omp critical
。
基本方法有点简单明了。您可以在没有任何OpenMP的情况下测量基准序列时间,并且只包含要测量的OpenMP pragma。然后,减去经过的时间。这正是EPCC基准测量开销的方式。请参阅“syncbench.c”等来源。
请注意,开销表示为时间,而不是周期数。我还尝试测量周期数,但OpenMP并行结构的开销可能包括由于同步而导致的阻塞时间。因此,周期数可能无法反映OpenMP的实际开销。