gpt4 book ai didi

c++ - 为什么串行执行比并行执行花费的时间更少?

转载 作者:行者123 更新时间:2023-12-01 22:35:47 25 4
gpt4 key购买 nike

我必须添加两个 vector 并将串行性能与并行性能进行比较。但是,我的并行代码的执行时间似乎比串行代码要长。

您能否建议更改以使并行代码更快?

#include <iostream>
#include <time.h>
#include "omp.h"
#define ull unsigned long long

using namespace std;

void parallelAddition (ull N, const double *A, const double *B, double *C)
{
ull i;

#pragma omp parallel for shared (A,B,C,N) private(i) schedule(static)
for (i = 0; i < N; ++i)
{
C[i] = A[i] + B[i];
}
}

int main(){

ull n = 100000000;
double* A = new double[n];
double* B = new double[n];
double* C = new double[n];

double time_spent = 0.0;


for(ull i = 0; i<n; i++)
{
A[i] = 1;
B[i] = 1;
}

//PARALLEL
clock_t begin = clock();
parallelAddition(n, &A[0], &B[0], &C[0]);
clock_t end = clock();
time_spent += (double)(end - begin) / CLOCKS_PER_SEC;

cout<<"time elapsed in parallel : "<<time_spent<<endl;


//SERIAL
time_spent = 0.0;
for(ull i = 0; i<n; i++)
{
A[i] = 1;
B[i] = 1;
}
begin = clock();
for (ull i = 0; i < n; ++i)
{
C[i] = A[i] + B[i];
}
end = clock();
time_spent += (double)(end - begin) / CLOCKS_PER_SEC;
cout<<"time elapsed in serial : "<<time_spent;
return 0;
}

这些是结果:

并行运行的时间: 0.824808

连续运行的时间: 0.351246

我在另一个线程上读到,存在线程生成、资源分配等因素。但我不知道该怎么做才能得到预期的结果。

<小时/>

编辑:

谢谢! @zulan 和 @Daniel Langr 的回答确实有帮助!

我使用了omp_get_wtime()而不是clock() 。恰好是clock()测量所有线程的累积时间,与 omp_get_wtime() 相比可用于测量从任意点到其他任意点所耗时

这个答案也很好地回答了这个问题:https://stackoverflow.com/a/10874371/4305675

这是固定代码:

void parallelAddition (ull N, const double *A, const double *B, double *C)
{
....
}

int main(){

....


//PARALLEL
double begin = omp_get_wtime();
parallelAddition(n, &A[0], &B[0], &C[0]);
double end = omp_get_wtime();
time_spent += (double)(end - begin);

cout<<"time elapsed in parallel : "<<time_spent<<endl;



....

//SERIAL
begin = omp_get_wtime();
for (ull i = 0; i < n; ++i)
{
C[i] = A[i] + B[i];
}
end = omp_get_wtime();
time_spent += (double)(end - begin);
cout<<"time elapsed in serial : "<<time_spent;
return 0;
}

更改后的结果:

并行时间: 0.204763

连续运行的时间: 0.351711

最佳答案

有多种因素会影响您的测量:

  1. 按照@zulan的建议使用omp_get_wtime(),否则,您实际上可能会计算组合CPU时间,而不是墙壁时间

  2. 线程有一些开销,并且通常对于短计算来说没有返回。您可能需要使用更高的n

  3. 在运行 parallelAddition 之前“触摸”C 数组中的数据。否则,内存页实际上是从操作系统内部的parallelAddition 中分配的。自 C++11 起即可轻松修复:double* C = new double[n]{};

我尝试了你的程序,n 为 1G,最后的更改将 2 个线程的 parallelAddition 运行时间从 1.54 减少到 0.94 [s]。串行版本需要 1.83 [s],因此,2 个线程的加速比为 1.95,非常接近理想状态。

其他注意事项:

  • 一般来说,如果您分析某些内容,请确保该程序具有一些可观察到的效果。否则,编译器可能会优化掉很多代码。您的数组添加没有明显的效果。

  • 将某种形式的restrict关键字添加到C参数中。如果没有它,编译器可能无法应用矢量化。

  • 如果您使用的是多插槽系统,请注意线程关联性和 NUMA 效果。在我的双插槽系统上,当将线程限制为单个 NUMA 节点 (numactl -N 0 -m 0) 时,2 个线程的并行版本的运行时间需要 0.94 [s](如上所述)。如果没有 numactl,则需要 1.35 [s],即 1.44 倍。

关于c++ - 为什么串行执行比并行执行花费的时间更少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com