Linux C/C++;MPI加速不如预期
我正在尝试编写一个MPI应用程序来加速计算机集群的数学算法。但在此之前,我正在做一些基准测试。但最初的结果并没有预期的那么多 测试应用程序具有4个核的线性加速,但5,6个核没有加速应用程序。我正在用Odroid N2平台进行测试。它有6个核。Nproc说有6个内核可用 我是否缺少某种配置?或者我的代码准备得不够好(它基于mpi的一个基本示例) 是否有需要考虑的响应时间或同步时间 以下是我的基于MPI的应用程序的一些措施。我测量了一个函数的总计算时间Linux C/C++;MPI加速不如预期,linux,performance,mpi,raspberry-pi4,odroid,Linux,Performance,Mpi,Raspberry Pi4,Odroid,我正在尝试编写一个MPI应用程序来加速计算机集群的数学算法。但在此之前,我正在做一些基准测试。但最初的结果并没有预期的那么多 测试应用程序具有4个核的线性加速,但5,6个核没有加速应用程序。我正在用Odroid N2平台进行测试。它有6个核。Nproc说有6个内核可用 我是否缺少某种配置?或者我的代码准备得不够好(它基于mpi的一个基本示例) 是否有需要考虑的响应时间或同步时间 以下是我的基于MPI的应用程序的一些措施。我测量了一个函数的总计算时间 1芯0.838052秒 2芯0.438483
- 1芯0.838052秒
- 2芯0.438483秒
- 3芯0.405501秒
- 4芯0.416391秒
- 5芯0.514472秒
- 6芯0.435128秒
- 12芯(3个N2板的4芯)0.06867秒
- 18芯(3个N2板的6芯)0.152759秒
- 1芯1.51秒
- 2芯0.75秒
- 3芯0.69秒
- 4芯0.67秒
int MyFun(int *array, int num_elements, int j)
{
int result_overall = 0;
for (int i = 0; i < num_elements; i++)
{
result_overall += array[i] / 1000;
}
return result_overall;
}
int compute_sum(int* sub_sums,int num_of_cpu)
{
int sum = 0;
for(int i = 0; i<num_of_cpu; i++)
{
sum += sub_sums[i];
}
return sum;
}
//measuring performance from main(): num_elements_per_proc is equal to 604800
if (world_rank == 0)
{
startTime = std::chrono::high_resolution_clock::now();
}
// Compute the sum of your subset
int sub_sum = 0;
for(int j=0;j<1000;j++)
{
sub_sum += MyFun(sub_intArray, num_elements_per_proc, world_rank);
}
MPI_Allgather(&sub_sum, 1, MPI_INT, sub_sums, 1, MPI_INT, MPI_COMM_WORLD);
int total_sum = compute_sum(sub_sums, num_of_cpu);
if (world_rank == 0)
{
elapsedTime = std::chrono::high_resolution_clock::now() - startTime;
timer = elapsedTime.count();
}
intmyfun(int*array,intnum\u元素,intj)
{
int结果_总体=0;
对于(int i=0;i0.36
6048个样本,MyFun呼叫1000000次:
1.43->0.7->0.47->0.35
6048个样本,MyFun呼叫10000000次:
14.43->7.08->4.72->3.59
更新2:
顺便说一下,当我在linux中列出CPU信息时,我得到了以下信息:
这正常吗?
四核A73核不存在。它说有两个3-3核的插座
以下是sar的CPU利用率:
似乎所有的核心都被利用了
我通过加速创建了一些绘图:
看起来用浮点计算而不是int有点帮助,但是核心5-6没有太大帮助。我认为内存带宽是可以的。当使用little.BIG架构平均利用所有CPU时,这是正常行为吗?如果num\u elements
很大,那么您的程序可能内存受限,并且在添加新代码时不会看到太多的速度提升核心。您可以执行简单的分析。取MyFun
的内部循环,计算执行一次迭代所需的周期数。计算从内存读取的字节数(假设result\u total
保存在寄存器中)。将处理器频率除以循环计数,再乘以字节数。将最大内存带宽除以该值,即可得到循环的独立副本数的理论限制,该循环可以同时运行,而不会影响每个副本的性能。感谢您的评论。元素总数为604800。这导致了2.3GB的RAM。N2有4GB的RAM。在临床上,RAM被分为第一部分,简单内存为3.5GB,还有一个1GB的Z RAM分区。不管怎样,你是说缓存绑定还是RAM绑定?我将用不同的大小做一个测试。我说的是最近级别的内存层次的带宽chy是两个核心之间共享的,并且大到足以容纳所有数据。如果我们谈论的是2,3 GB的数据,那显然是RAM。但是604800个整数实际上只需要几MB,因此它们可能也可以放入二级缓存。请确保您告诉MPI库将列组固定到适当的CPU核心,因为2的SoC是大的。小的,将两个核心集群混合在一个工作中,使每个级别都有相同的工作量,这是非常低效的。是的,小的核心减慢了一切。如果你想充分利用所有6个核心,你应该采用适合异构体系结构的工作分配策略,例如,分配任务的策略友好地或根据某些性能度量调整任务大小的程序。如果num\u elements
很大,则您的程序可能内存不足,并且在添加新内核时不会看到太大的速度。您可以执行简单的分析。使用MyFun
的内部循环,计算执行一次迭代所需的周期数。计算h它从内存中读取的字节数(假设result\u总的来说保存在寄存器中)。将处理器频率除以循环计数,再乘以字节数。将最大内存带宽除以该值,即可得到循环的独立副本数的理论限制,该循环可以同时运行,而不会影响每个副本的性能。感谢您的评论。元素总数为604800。这导致了2.3GB的RAM。N2有4GB的RAM。在临床上,RAM被分为第一部分,简单内存为3.5GB,还有一个1GB的Z RAM分区。不管怎样,你是说缓存绑定还是RAM绑定?我将用不同的大小做一个测试。我说的是最近级别的内存层次的带宽chy是两个核心之间共享的,并且大到足以容纳所有数据。如果我们谈论的是2,3 GB的数据,那显然是RAM。但是604800个整数实际上只需要几MB,因此它们可能也可以放入二级缓存。请确保您告诉MPI库将列组固定到适当的CPU核心,因为2的SoC是大的。小的,将两个核心集群混合在一个工作中,使每个级别都有相同的工作量,这是非常低效的。是的,小的核心减慢了一切。如果你想充分利用所有6个核心,你应该采用适合异构体系结构的工作分配策略,例如,分配任务的策略友好地或根据某个绩效调整任务大小的人