我制作了一个计算斐波纳契序列的程序。我使用不同数量的线程(例如,1,2,10)执行它,但执行时间几乎保持不变(约0.500秒)。
我在Ubuntu和GNU GCC编译器上使用CodeBlocks。在CodeBlocks中,我链接了库gomp
并为编译器定义了标志-fopenmp
。
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, n=1000, a[n];
omp_set_num_threads(4);
for(i=0; i<n; i++)
{
a[i] = 1 + (rand() % ( 50 - 1 + 1 ) );
}
fibo(n, a);
return 0;
}
void fibo(int sizeN, int n[])
{
int i;
#pragma omp parallel for
for(i=0; i<sizeN; i++)
{
int a = 0, b = 1, next, c;
printf("n = %i\n", n[i]);
for (c=0; c<=n[i]; c++)
{
if (c <= 1)
{
next = c;
}
else
{
next = a + b;
a = b;
b = next;
}
printf("%d\n",next);
}
}
}
有人有想法吗?
如何确保OpenMP真正起作用(已安装)?
答案 0 :(得分:2)
删除两个printf
语句。您的程序花费更多时间将文本发送到标准输出而不是计算数字。由于标准输出基本上是串行的,因此您的程序会在printf
语句中序列化。更不用说printf
本身的开销 - 它必须解析格式字符串,将整数值转换为字符串,然后将其发送到stdout
流。
观察那些测量时间(n = 10000
):
OMP_NUM_THREADS=1 ./fibo.exe 0.10s user 0.42s system 40% cpu 1.305 total
^^^^^^^^^^^^
OMP_NUM_THREADS=2 ./fibo.exe 0.24s user 1.01s system 95% cpu 1.303 total
^^^^^^^^^^^^
OMP_NUM_THREADS=4 ./fibo.exe 0.36s user 1.87s system 163% cpu 1.360 total
^^^^^^^^^^^^
我删除了对omp_set_num_threads()
的调用并改为使用OMP_NUM_THREADS
,这允许使用不同数量的线程运行程序而无需重新编译源代码。请注意,该程序在系统模式下的使用时间始终比用户模式多4倍。这是该文本输出的开销。
现在将两个printf
语句进行比较(注意我必须将n
增加到1000000
才能从time
获得有意义的结果):< / p>
OMP_NUM_THREADS=1 ./fibo.exe 0.20s user 0.00s system 99% cpu 0.208 total
^^^^^^^^^^^
OMP_NUM_THREADS=2 ./fibo.exe 0.21s user 0.00s system 179% cpu 0.119 total
^^^^^^^^^^^
OMP_NUM_THREADS=4 ./fibo.exe 0.20s user 0.01s system 295% cpu 0.071 total
^^^^^^^^^^^
现在系统时间几乎为零,程序速度提高了1,75倍,2个线程速度提高了2,93倍。加速不是线性的,因为螺纹之间的工作分布存在轻微的不平衡。如果数组填充了常数值,则加速几乎是线性的。
答案 1 :(得分:0)
尝试要求更大的常数(非随机)的fibbonacci值,以及更大的sizeN
值。然后,您应该使用相同的值进行测试,但使用串行实现(删除#pragma
并重新编译)。
此外,您的系统中应该有多个核心,以便从并行性中获得一些好处。
最后,如果它通过-fopenmp
进行编译,则会安装OpenMP。