我想让我的程序运行得更快,所以我会使用并行计算。在此之前,我尝试使用简单的for循环,但运行速度较慢。
在打开mp之前:
int a[100000] = { 0 };
clock_t begin = clock();
for (int i = 0; i < 100000; i++)
{
a[i] = i;
}
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
printf("%lf", elapsed_secs);
打开mp后:
int a[100000] = { 0 };
clock_t begin = clock();
#pragma omp parallel for
for (int i = 0; i < 100000; i++)
{
a[i] = i;
}
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
printf("%lf", elapsed_secs);
答案 0 :(得分:2)
你说你的代码运行速度较慢,但实际上你并不知道。原因是您使用clock()
来测量时间,此函数计算当前线程的 CPU 时间,并可能计算它产生的所有线程之一 。为了评估加速,您需要测量的是经过的挂钟时间。为此,OpenMP为您提供omp_get_wtime()
。尝试在代码上使用它,然后您真的知道您的代码是否从OpenMP中获得任何好处。
现在,让我们清楚一点,你的代码只是写在内存中。因此很有可能您很快就会使内存带宽饱和。因此,除非您有多个内存控制器,否则在这种情况下添加线程不太可能获得太多收益。请查看this answer以说服自己。
最后,确保在退出代码之前对数据执行某些操作,否则,编译器可能只是优化它,导致代码几乎没有做任何事情(但是执行速度非常快)。 / p>
答案 1 :(得分:1)
要成功完成第一个OpenMP并行(多线程)代码示例,您需要从以下两个角度改进测试用例:
让您的示例可测试。要做到这一点:
确保你的循环在每次循环迭代中都做了足够的(理想的计算)工作(即添加,乘法等),以便各种 开销 与在OpenMP运行时库中进行一些底层工作相关联(需要“安排”/计划/分配线程之间的迭代)不是“更大”而不是有用工作量< / strong>在一堆循环迭代中完成。 第二和第三维基百科OpenMP' parallel for examples已经足够大,可以满足给定的标准(而你的例子并不令人满意)。您只需遵循维基百科示例即可帮助您获得一些基本的理解。
在你学习了基础知识之后,接下来的步骤将是(a)理解“数据竞赛”/“竞争条件”/“循环携带依赖关系”和(b)理解#pragma omp parallel和#pragma之间的“差异” omp for(再次,你需要从书籍或基本的OpenMP课程中找到简单的例子)。
(老实说,所有其他主题,如OpenMP不平衡,动态与静态,内存带宽,只有在您花费至少几天阅读/练习更简单的概念后才有意义)