C++性能优化系列

您所在的位置:网站首页 矩阵转置的代码有哪些 C++性能优化系列

C++性能优化系列

2023-11-18 10:33| 来源: 网络整理| 查看: 265

在上一篇博客 C++性能优化系列——矩阵转置(二)循环分块优化缓存访问 中通过循环分块方法,分析并优化了缓存的访问,使性能得到提升。同时通过VTune抓包分析了代码执行情况。看起来Cache命中情况很好。可实际缓存真的没有优化空间了吗?也不见得。 本篇根据《深入理解计算机系统》中缓存篇介绍的映射规则,在缓存映射方面做进一步优化。以分块优化版本为Base,通过对pSource数据进行内存填充处理,使pSource的访问内存映射不集中在一个缓存组中,避免缓存抖动问题。 优化后执行情况: 1024 * 1024 二维矩阵转置耗时 0.367188 ms

内存映射模式分析

《深入理解计算机系统》这本书中已经对缓存的映射关系说的非常清楚了,有兴趣同学可以详细阅读书中具体章节。(这里感触比较深,书中几页纸就把问题说的非常清楚了,极其不建议把时间耗费在阅读网上各种几千几万阅读量的博客上,博客质量真是无力吐槽)。 在此主要说明测试环境内存与L1 D-Cache的映射。 L1 D-Cache参数:32k,8路组映射,缓存行(Cache Line)64Bytes。L1 D-Cache中一共存在(32k / (8 * 64Byte)= 64 组。 因此,当以一定间隔访问内存时,理论上间隔 为(64组 * 64 Byte = 4k )的内存跨度时,对应的内存会映射到同一个缓存组中。当访问内存时,超过8个分散的数据都映射到同一个组中,按照缓存的局部性原则,之前加载进缓存的数据会被新的数据替换。即缓存抖动问题。 Base版本的实现是以 128 * 128 分块,在内层访问块内数据。pSource的行维度为1024,因此即便是以128进行分块,内存访问的总跨度也达到了128K,按照之前分析的规则,在一个块内访问一列数据时,每4个元素会映射到同一个组中,即有32个元素的内存会映射到相同的缓存组,因此会发生缓存抖动。 解决缓存抖动问题常用的方法是内存填充,即增加pSource行的维度,这样访问逻辑上同一列的元素时,实际内存位置不会映射在相同的缓存组。对于最优的内存填充方案,目前本人还没来得及查阅相关文献。代码中是通过取若干组数据实验出的最优填充值。

代码实现

矩阵尺寸相关宏定义,其中增加了内存填充后的pSource的行的维度NREALCOL

#define NREALCOL 1152 #define NROW 1024 #define NCOL 1024 #define NSLICE NROW*NCOL #define REPEAT 1024 #define BLOCK 128

代码实现如下:

void PaddingTranspose(unsigned char* pSource, unsigned char* pTarget) { //Target 连续访问行 //PaddingTranspose Time (ms) 0.367188 clock_t begin = clock(); int nbC = NCOL / BLOCK, nbR = NROW / BLOCK; for (int i = 0; i for (int ibc = 0; ibc for (int icol = 0; icol


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3