首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >分子动力学模拟

分子动力学模拟
EN

Code Review用户
提问于 2020-03-19 10:25:11
回答 1查看 167关注 0票数 3

我正在寻找一些关于如何在我的C++代码中优化几个函数的新想法。我通过一个分析器运行代码,它显示了它们分别占用了20%和40%的时间。这些函数被多次调用,因为它们驻留在一个三重嵌套循环中(无法避免)。

blip3_inner(args...) (20%的时间)如下:

代码语言:javascript
运行
复制
   void PairBlip::blip3_inner(int &i, int &j, int &k, int &e,double g[][2][3],
                                 double gp[][2][3] ,double &blip_ijk, double coef[2])                                                                      
    {                                                                                                                                                                                                     
        double f[3][2][3];                                                                                                                                                                                
        for (int d=0; d<3; ++d)                                                                                                                                                                           
            for (int a=0; a<2; ++a)                                                                                                                                                                       
                for (int b=0; b<3; ++b)                                                                                                                                                                   
                    f[d][a][b] = gp[d][a][b] * blip_ijk - g[d][a][b] * coef[a];                                                                                                                           

        blip3_dump(i,j,k,e,f);                                                                                                                                                                            
    }       

blip3_dump(args...) (40%的时间)是:

代码语言:javascript
运行
复制
    void PairBlip::blip3_dump(int &i, int &j, int &k, int &e, double f[][2][3])                                                                                                                           
    {                                                                                                                                                                                                     
        for (int d=0; d<3; ++d)                                                                                                                                                                           
        {                                                                                                                                                                                                 
            for (int b=0; b<3; ++b)                                                                                                                                                                       
            {                                                                                                                                                                                             
                force_fp[i][d][e+size2b+b*size_grid_3b] += f[d][0][b] + f[d][1][b];                                                                                                                       
                force_fp[j][d][e+size2b+b*size_grid_3b] -= f[d][0][b];                                                                                                                                    
                force_fp[k][d][e+size2b+b*size_grid_3b] -= f[d][1][b];                                                                                                                                    
            }                                                                                                                                                                                             
        }                                                                                                                                                                                                 

    }  

代码使用以下标志进行编译:

代码语言:javascript
运行
复制
-g -std=c++11 -O3 -ffast-math -march=native

代码将用于体系结构的范围,编译器标志的选择实际上取决于最终用户。

整个代码都是用MPI并行化的,所以上面的函数是由单个核计算的。

对于第二个函数,我尝试将堆上声明的force_fp替换为堆栈上声明的中间变量。虽然它在使用-O编译时有所改进,但在使用-O3时,任何好处都会消失。

如果有任何想法,我将不胜感激。

背景

我正在开发机器学习原子间对潜能,以便与https://lammps.sandia.gov/一起工作。代码的结构非常类似于经典的三体势,如Tersoff或Stillinger。上述代码在嵌套的ijk循环中被调用,其中i遍历盒中的所有原子,jki的总体近邻。情况就是这样,没有改进的余地。

<#>更新

我尝试通过扁平blip3_inner()g[18]gp[18]来减少许多嵌套循环并改进缓存,但它并没有提高速度。

EN

回答 1

Code Review用户

回答已采纳

发布于 2020-03-19 12:31:53

blip3_dump()的S偏移表达式引入一个变量:

代码语言:javascript
运行
复制
    for (int b=0, e_size2b = e + size2b; b<3; ++b) {
        int offset = e_size2b + b * size_grid_3b;
        for (int d=0; d<3; ++d) {
            force_fp[i][d][offset] += f[d][0][b] + f[d][1][b];
            force_fp[j][d][offset] -= f[d][0][b];
            force_fp[k][d][offset] -= f[d][1][b];
        }
    }

请注意,这是如何展开“a-loop”的--更明显的是使用单独的force_fp[i]更新。在PairBlip::blip3_inner()中,展开a-loop并交换第一个和最后一个索引:

代码语言:javascript
运行
复制
    for (int b=0; b<3; ++b)
        for (int d=0; d<3; ++d) {
            f[d][0][b] = gp[d][0][b] * blip_ijk - g[d][0][b] * coef[0];
            f[d][1][b] = gp[d][1][b] * blip_ijk - g[d][1][b] * coef[1];
        }

这似乎建议将f[][][]和关联索引替换为f0f1

代码语言:javascript
运行
复制
void blip3_inner(int i, int j, int k, int e_size2b,
        double g[][2][3], double gp[][2][3],
        double &blip_ijk, double coef[2])
{
    for (int b=0; b<3; ++b) {
        int offset = e_size2b + b * size_grid_3b;
        for (int d=0; d<3; ++d) {
            double  f0 = gp[d][0][b] * blip_ijk - g[d][0][b] * coef[0],
                    f1 = gp[d][1][b] * blip_ijk - g[d][1][b] * coef[1];
            force_fp[i][d][offset] += f0 + f1;
            force_fp[j][d][offset] -= f0;
            force_fp[k][d][offset] -= f1;
        }
    }
}
票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/239139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档