C++ 访问数组效率对比

C++ 访问数组效率对比

在C++中, 访问一个多维数据有很多方式, 例如使用[ ], 使用指针等. 这里, 我们考虑以下五种方式, 并计算他们运行的时间. 以二维数组为例,

  1. 按行访问, row major.
    for (int i = 0; i < resolution; i++) {
        for (int j = 0; j < resolution; j++) {
            arr[i][j] = i;
        }
    }
    
  2. 按列访问, col major.
    for (int i = 0; i < resolution; i++) {
       for (int j = 0; j < resolution; j++) {
            arr[j][i] = i;
        }
    }
    
  3. 使用指针, 当做一维数组线性递增寻址访问.
    for (int i = 0; i < res_square; i++) {
        *(arr_ptr + i) = i;
    }
    
  4. 使用指针, 双循环按行计算地址后寻址访问.
    for (int i = 0; i < resolution; i++) {
       for (int j = 0; j < resolution; j++) {
            *(arr_ptr + i * resolution + j) = i;
        }
    }
    
  5. 使用指针, 双循环按列计算地址后寻址访问.
    for (int i = 0; i < resolution; i++) {
        for (int j = 0; j < resolution; j++) {
            *(arr_ptr + j * resolution + i) = i;
        }
    }
    

const int K = 100; const int resolution = 4096;的情况下, g++开启O6优化, 每种方式测试 K 次, 统计每种访问方式的时间为

1row major, test 100 times, average cost 0.0051966 s
2col major, test 100 times, average cost 0.0350176 s
3row major pointer, test 100 times, average cost 0.00527759 s
4row major pointer, test 100 times, average cost 0.00530057 s
5col major pointer, test 100 times, average cost 0.0346161 s

关闭编译器优化后, 结果如下

1row major, test 100 times, average cost 0.0326994 s
2col major, test 100 times, average cost 0.270378 s
3row major pointer, test 100 times, average cost 0.0355432 s
4row major pointer, test 100 times, average cost 0.0253486 s
5col major pointer, test 100 times, average cost 0.276818 s

notice: 值得注意的是, 第三种方式的执行效率是比第四中低的. 直觉上, 线性寻址应该会比双循环计算更快. 并且第四种方式的效率高于第一种和第三种. 对此, 有人给出了一下解释, mark一下:
用cpu工具大概看了下,第四种比第三种更优是因为拆开后自增依赖降低了,所以流水线能够更有效的隐藏延迟.

另外, 这也反映了c++数组是按行优先存储的.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值