Page 87 - 《软件学报》2024年第6期
P. 87

方燕飞 等: 申威众核处理器访存与通信融合编译优化                                                       2663


                 掉主存中的有用数据, 需要根据实际循环大小修正数据量.
                    Step 5. 进行回答字测试优化, 多个相邻的        DMA  操作, 其回答字测试可以合并, 减少开销.

                 5   实验验证
                    本节对设计实现的访存优化编译技术进行实验验证和分析. 测试平台为基于                          SW26010Pro  构建的计算系统,
                 安装部署了本文设计实现的融合优化编译指示的编程语言环境. 在实际应用中, 也可将                            3  种优化类型的编译指示
                 同时作用在同一个循环的多个数组访问中, 产生叠加的优化效果. 在本实验中, 为分别展示                           3  种优化类型的编译指
                 示的效果, 本文选取了      3  个使用不同优化模式的测试用例分别进行了实验测试与分析.

                 5.1   编译指示使用示例及代码量对比分析
                    本节通过代码量对比示例直观展示使用本文设计的编译指示进行优化编程的效果. 其中图                               14  为基于编译指
                 示的单、双缓冲程序代码示意, 图           15、图  16  为手工实现的相同优化效果的程序代码示意. 通过对比代码量可以
                 看出使用本文设计的编译指示进行编程优化, 大幅减小了编程工作量, 实现的程序代码更简洁.

                      dma_get(ldm_poses[k],&poses[k][CCC_TID*WGSIZE][bix
                     /*单缓冲优化编译指示编程示例*/                       /*双缓冲优化编译指示编程示例*/
                     #define WGSIZE 4096                     #define WGSIZE 4096
                     float LDM_Tbuf = (float *)ldm_malloc(5*1024)  float LDM_Tbuf = (float *)ldm_malloc(  10*1024)
                     #pragma ccc sbuf mem2ldm(poses) \       #pragma ccc  dbuf mem2ldm(poses) \
                                 ldm_addr(LDM_Tbuf) ldm_size(5120)         ldm_addr(LDM_Tbuf) ldm_size( 10240 )
                     for(int ix=0; ix<WGSIZE; ix++)          for(int ix=0; ix<WGSIZE; ix++)
                     {                                       {
                         //Compute transformation matrix          //Compute transformation matrix
                         const float sx = sinf(poses[0][CCC_TID*WGSIZE][ix]);  const float sx = sinf(poses[0][CCC_TID*WGSIZE][ix]);
                         const float cx = cosf(poses[0][CCC_TID*WGSIZE][ix]);  const float cx = cosf(poses[0][CCC_TID*WGSIZE][ix]);
                         const float sy = sinf(poses[1][CCC_TID*WGSIZE][ix]);  const float sy = sinf(poses[1][CCC_TID*WGSIZE][ix]);
                         const float cy = cosf(poses[1][CCC_TID*WGSIZE][ix]);  const float cy = cosf(poses[1][CCC_TID*WGSIZE][ix]);
                         const float sz = sinf(poses[2][CCC_TID*WGSIZE][ix]);  const float sz = sinf(poses[2][CCC_TID*WGSIZE][ix]);
                         const float cz = cosf(poses[2][CCC_TID*WGSIZE][ix]);  const float cz = cosf(poses[2][CCC_TID*WGSIZE][ix]);
                         …//其他与优化无关代码                             …//其他与优化无关代码
                         Transform[0][3][ix] = poses[3][CCC_TID*WGSIZE][ix];  Transform[0][3][ix] = poses[3][CCC_TID*WGSIZE][ix];
                         …//其他与优化无关代码                             …//其他与优化无关代码
                         Transform[1][3][ix] = poses[4][CCC_TID*WGSIZE][ix];  Transform[1][3][ix] = poses[4][CCC_TID*WGSIZE][ix];
                         …//其他与优化无关代码                             …//其他与优化无关代码
                         Transform[2][3][ix] = poses[5][CCC_TID*WGSIZE][ix];  Transform[2][3][ix] = poses[5][CCC_TID*WGSIZE][ix];
                         …//其他与优化无关代码                             …//其他与优化无关代码
                     }                                       }
                                        图 14 基于编译指示的单、双缓冲优化程序代码示意

                      //手工单缓冲优化编程示例                              for(int ix=0; ix<BLOCK;ix++)
                      #define WGSIZE 4096                        {
                      #define BLOCK 256                            //Compute transformation matrix
                      float LDM_Tbuf=(float*)ldm_malloc(5*1024)    const float sx = sinf(ldm_poses[0][ix]);
                      float *ldm_poses[5];                         const float cx = cosf(ldm_poses[0][ix]);
                      for (int k=0;k<5;k++)                        const float sy = sinf(ldm_poses[1][ix]);
                      {                                            const float cy = cosf(ldm_poses[1][ix]);
                         ldm_poses[k]=LDM_Tbuf[BLOCK*k];           const float sz = sinf(ldm_poses[2][ix]);
                      }                                            const float cz = cosf(ldm_poses[2][ix]);
                      for(int bix=0;bix<WGSIZE;bix+=BLOCK)         …//其他与优化无关代码
                      {                                            Transform[0][3][ix] =ldm_poses[3][ix];
                         for(int k=0;k<5;k++)                      …//其他与优化无关代码
                         {                                         Transform[1][3][ix] =ldm_poses[4][ix];
                                                                   …//其他与优化无关代码
                      ], sizeof(float)*BLOCK,MEM_TO_LDM);          Transform[2][3][ix] =ldm_poses[5][ix];
                         }                                         …//其他与优化无关代码
                                                                }//ix
                                                              }//bix
                                           图 15 手工实现的单缓冲优化程序代码示意
   82   83   84   85   86   87   88   89   90   91   92