英特尔至强E5-2650性能下的C代码

时间:2015-01-07 13:50:11

标签: c openmp vectorization intel hpc

我有一个c代码(Open MP并行化),在英特尔至强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是一个struct数组。 acc是pdata [i]的成员,并且有成员x,y和z。 struct pdata也有许多其他数据成员。数据参数的成员涉及像pow这样的数学函数。 上面发布的代码是我的探查器中显示的占用最长时间的部分之一。

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

谢谢。感谢您的耐心

1 个答案:

答案 0 :(得分:1)

示例代码似乎使用了一组结构,这是N体仿真的经典表现不佳的主题,等等。你应该阅读AoS-to-SoA转换,其中SoA是数组结构,几乎总是计算我认为你想要计算的东西的正确方法。

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

如果存在循环不变量,则应将它们从循环中拉出来,并可能使用单个指针替换这些高度间接访问,然后使用该指针迭代数据。我不知道这样做有多容易,也不知道它有多好,但如果我是你,那就是我开始的地方。

“AoS-to-SoA转换”中有许多谷歌点击率;其中有https://software.intel.com/en-us/articles/memory-layout-transformations,这似乎与你的情况特别相关。