c++ - 堆栈分配功能(性能)

标签 c++ c performance stack allocation

在我的小性能问题调查中,我注意到一个有趣的堆栈分配功能,这里是测量时间的模板:

#include <chrono>
#include <iostream>

using namespace std;
using namespace std::chrono;

int x; //for simple optimization suppression
void foo();

int main()
{   
    const size_t n = 10000000; //ten millions
    auto start = high_resolution_clock::now();

    for (size_t i = 0; i < n; i++)
    {
        foo();
    }

    auto finish = high_resolution_clock::now();
    cout << duration_cast<milliseconds>(finish - start).count() << endl;
}

现在是关于foo()的实现,在每个实现中将总共分配500000个整数:

  1. 分配在一个 block 中:

    void foo()
    {
        const int size = 500000;
        int a1[size];
    
        x = a1[size - 1];
    }  
    

    结果:7.3秒

  2. 分配在两个 block 中:

    void foo()
    {
        const int size = 250000;
        int a1[size];
        int a2[size];
    
        x = a1[size - 1] + a2[size - 1];
    }
    

    结果:3.5秒

  3. 分配在四个 block 中:

    void foo()
    {
        const int size = 125000;
        int a1[size];
        int a2[size];
        int a3[size];
        int a4[size];
    
        x = a1[size - 1] + a2[size - 1] +
            a3[size - 1] + a4[size - 1];
    } 
    

    结果:1.8 秒

等等...我将其分成16 个 block 并得到结果时间0.38 秒


请给我解释一下,这是为什么以及如何发生的?
我使用 MSVC 2013 (v120),发布版本。

更新:
我的机器是x64平台。并且我是用Win32平台编译的。
当我使用 x64 平台编译它时,它在所有情况下都会产生大约 40 毫秒。
为什么平台选择影响如此之大?

最佳答案

查看 VS2015 更新 3 的反汇编,在 foo 的 2 和 4 数组版本中,编译器优化了未使用的数组,以便它仅为每个函数中的 1 个数组保留堆栈空间。由于后面的函数具有较小的数组,因此花费的时间较少。对 x 的赋值读取两个/所有 4 个数组的相同内存位置。 (由于数组未初始化,从中读取是未定义的行为。)如果不优化代码,则会读取 2 或 4 个不同的数组。

这些功能花费的时间很长是由于 __chkstk 执行的堆栈探测。作为堆栈溢出检测的一部分(当编译器需要超过 1 页的空间来保存所有局部变量时是必需的)。

关于c++ - 堆栈分配功能(性能),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38840442/

相关文章:

c# - C# 中的 WebRequests 是非常 CPU 密集型的。需要更好的东西

c++ - BOOST ASIO POST HTTP REQUEST——标题和正文

c++ - 将 block 从 Objective-C 传递给 C++ 方法

c++ - 将二进制数的字符数组转换为C++中格雷码的计数器

c++ - C++ 中的命名冲突 : How to access a struct member called "class"

函数原型(prototype) dlsym 的 C typedef

c++ - line 是什么意思?

c++ - 未使用的默认参数会降低性能 C++

php - jmeter多用户问题

c++ - 为什么我不能将 "->"与 "this"和 "[ ]"一起使用?