C 代码在 Intel Xeon E5-2650 上的性能

标签 c openmp vectorization intel hpc

我有一个 C 代码(Open MP 并行化),在 Intel Xeon E5-2650 节点(全部 16 个内核)上运行所需的时间是在配备 Intel i 7 处理器的桌面上运行的时间的两倍多。通过标准基准测试案例,我的计算节点提供了令人满意的性能。我意识到这与我的代码在现代处理器上运行的效率有关。有人可以指导我了解代码中可以改进的方面吗?我遇到过矢量化等问题,但是我无法找到有关此类问题的清晰的分步教程或文档。 关于代码:

该代码是模拟粒子相互作用。在识别出社区后,它们进行交互、计算和存储数据。粒子是结构体数组。交互函数示例如下所示。

static void interact(particleData *pdata, int a, int b, interactParams params)
{

  int i;
  double rdotdwdx = 0.0, vdotr =0.0;
  for(i=0;i<dim;i++){
    rdotdwdx += (&params.xr.x)[i]*(&params.dwdx.x)[i];
    vdotr += (&params.vr.x)[i]*(&params.xr.x)[i];
  }
  double Fab = vdotr/(params.rdotr + 0.0001*params.h*params.h);
  double acc;

  for(i = 0; i < dim; i++){

    acc = 8.*(((pdata[a].eta/pdata[a].rho)+(pdata[b].eta/pdata[b].rho)) /(pdata[a].rho+pdata[b].rho))*Fab*(&params.dwdx.x)[i];
    (&pdata[a].acc.x)[i] +=  acc*pdata[b].mass;
    (&pdata[b].acc.x)[i] += -acc*pdata[a].mass;
    }
  }
}

这里的pdata是一个结构体数组。 acc 是 pdata[i] 的成员,并且具有成员 x、y 和 z。 struct pdata 还有许多其他数据成员。 data param 的成员涉及 pow 等数学函数。 上面发布的代码是我的分析器中显示为消耗最多时间的部分之一。

我在两台机器上使用的编译器都是gcc。

谢谢。感谢您的耐心

最佳答案

示例代码似乎使用了结构数组,这是 N 体模拟等方面表现不佳的经典主题。您应该阅读 AoS 到 SoA 的转换,其中 SoA 是数组结构,并且几乎总是计算我认为您正在尝试计算的内容的正确方法。

除了使用 AoS 主题之外,您的循环还充满了大量间接代码。您应该查找 (&pdata[a].acc.x)[i] 的程序集,并准确查看分配给该数量需要多少条指令。

如果存在循环不变量,您应该将它们从循环中取出,并可能将这些高度间接的访问替换为使用单个指针的访问,然后使用该指针迭代数据。我不知道这有多容易做到,也不知道效果如何,但如果我是你,我就会从这里开始。

“AoS 到 SoA 转换”在 Google 上有很多点击;其中有https://software.intel.com/en-us/articles/memory-layout-transformations ,这似乎与您的案例特别相关。

关于C 代码在 Intel Xeon E5-2650 上的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27820959/

相关文章:

c++ - 这个编译器消息(矢量化,GCC)是什么意思?

multithreading - 创建的线程数为12,但仍只能在12个核心CPU的一个核心上运行

c - OMP 2.0 嵌套 For 循环

performance - 如何在不循环的情况下在 MATLAB 中乘以张量?

C RS232 通讯。如何比较CPU时间?

c - OSX 10.11 上的 OpenMP 支持,gcc 错误 "file omp.h not found"

python - 计算沿轴的直方图

c - 为什么 gcc 不支持将动态库链接到静态二进制文件

客户端服务器实现: (a newbie)

C嵌套结构指针问题