击中CPU缓存以提高C ++性能

问题描述

正在使用CPU缓存首选的连续缓冲区吗?

我正在尝试编写一个对图像执行多项操作的应用程序(一些非常局部的操作,例如移位,导数,以及一些结果之间的操作,例如减法)。 我为结果留了一个大缓冲区(每次计算都具有图像的形状,因此我从分配X *图像形状字节开始)

我该怎么做才能最大化CPU缓存命中率?

解决方法

当然,对连续数组进行操作更有可能命中缓存。
您可能需要连续排列数据:
例如:

#include <iostream>
#include <cstdint>

const int SIZE = 3;

int main(){
    uint8_t buffer_2d[SIZE][SIZE];
    uint8_t* buffer_1d = reinterpret_cast<uint8_t*>(buffer_2d); // or just do uint8_t buffer_1d[SIZE*SIZE];
    const auto base = &(buffer_2d[0][0]);
    for (int y=0;y<SIZE;++y){
        for (int x=0;x<SIZE;++x){
            std::cout << "x: " << x << " y: " << y << " offset for [x][y]: " << &(buffer_2d[x][y]) - base << " offset for [y][x]: " << &(buffer_2d[y][x]) - &(buffer_2d[0][0]) << " offset for [y*SIZE+x]: " << &(buffer_1d[y*SIZE+x]) - base <<  std::endl;
        }
    }
    return 0;
}

将数组作为人为自然的[x][y]数组进行处理将是无效的,因为数据不是以这种方式对齐的,所以有效的方法是使用[y][x]或将数组作为单个数组处理维数组,并将索引视为y*LINE_SIZE + x
这是此测试的输出,准确地表明了这一点:

x: 0 y: 0 offset for [x][y]: 0 offset for [y][x]: 0 offset for [y*SIZE+x]: 0
x: 1 y: 0 offset for [x][y]: 3 offset for [y][x]: 1 offset for [y*SIZE+x]: 1
x: 2 y: 0 offset for [x][y]: 6 offset for [y][x]: 2 offset for [y*SIZE+x]: 2
x: 0 y: 1 offset for [x][y]: 1 offset for [y][x]: 3 offset for [y*SIZE+x]: 3
x: 1 y: 1 offset for [x][y]: 4 offset for [y][x]: 4 offset for [y*SIZE+x]: 4
x: 2 y: 1 offset for [x][y]: 7 offset for [y][x]: 5 offset for [y*SIZE+x]: 5
x: 0 y: 2 offset for [x][y]: 2 offset for [y][x]: 6 offset for [y*SIZE+x]: 6
x: 1 y: 2 offset for [x][y]: 5 offset for [y][x]: 7 offset for [y*SIZE+x]: 7
x: 2 y: 2 offset for [x][y]: 8 offset for [y][x]: 8 offset for [y*SIZE+x]: 8

最后两个结果使用完全相同的语义,第一个结果将让编译器发出计算结果,但性能应相同。

此外,一旦正确地排列了数据,则取决于您对数据的处理方式,您可能希望使用OpenCL或其他东西并利用GPU或SIMD,如果可以用SIMD表示(单指令,则可能会带来显着的性能改进)。多个数据)代码。

,
#ifdef _MSC_VER
        _declspec(align(64))    unsigned char  block_hashfp;
#else
        __attribute__((aligned(64))) unsigned char  block_hashfp;
#endif

将进入二级缓存

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...