bobobobo Asked: 2024-04-13 22:14:21 +0800 CST2024-04-13 22:14:21 +0800 CST 2024-04-13 22:14:21 +0800 CST 为什么大型堆栈分配没有时间成本 772 我尝试了这个快速基准测试,发现分配 200 字节与分配 2000000 字节的时间成本相同。 怎么可能? c++ 2 个回答 Voted Best Answer Eric Postpischil 2024-04-13T22:29:54+08:002024-04-13T22:29:54+08:00 为什么大型堆栈分配没有时间成本 分配只不过是一个会计程序。对于堆栈分配,除了更改堆栈指针的值之外,可能不需要做任何其他事情。将 2,000,000 添加到堆栈指针的值并不比添加 200 花费更多的时间。 一旦堆栈发生更改,可能会产生后果。您尚未显示的程序可能会继续使用堆栈指针新位置周围的内存。如果是在新使用的虚拟内存页面中,第一次使用此类内存可能会产生一些开销,因为硬件会触发异常,操作系统将为该页面提供物理内存。但是,这种情况会在使用内存时发生,并且无论分配 2,000,000 还是 20,000,000 字节,情况都大致相同。与 200 字节相比,它可能相同也可能不同,因为 200 字节的更改可能会也可能不会将堆栈指针移动到新页面。 尝试使用新分配的内存是另一回事,因为读取或写入内存的成本通常与所使用的内存量呈线性关系(并且可能仅涉及对内存的硬件访问,也可能涉及进一步的操作系统干预,具体取决于具体情况) 。 分配使用malloc大致相同。核算会比仅仅更改堆栈指针更复杂,但它基本上仍然只是以较低的开销时间检查和更新一些数据结构,与分配的空间量不成正比。 user12002570 2024-04-13T22:24:23+08:002024-04-13T22:24:23+08:00 char buf[ N ]未buf 初始化,即其所有元素都有未确定的值。因此,在所有三个测试用例中,您实际上并没有初始化数组,而只是分配内存。 要查看实际差异,请添加大括号以对数组进行零初始化,如下所示: //-----------vv---->added these braces for initilization char buf[ N ]{}; 现在您可以看到这个修改后的演示的不同之处。
分配只不过是一个会计程序。对于堆栈分配,除了更改堆栈指针的值之外,可能不需要做任何其他事情。将 2,000,000 添加到堆栈指针的值并不比添加 200 花费更多的时间。
一旦堆栈发生更改,可能会产生后果。您尚未显示的程序可能会继续使用堆栈指针新位置周围的内存。如果是在新使用的虚拟内存页面中,第一次使用此类内存可能会产生一些开销,因为硬件会触发异常,操作系统将为该页面提供物理内存。但是,这种情况会在使用内存时发生,并且无论分配 2,000,000 还是 20,000,000 字节,情况都大致相同。与 200 字节相比,它可能相同也可能不同,因为 200 字节的更改可能会也可能不会将堆栈指针移动到新页面。
尝试使用新分配的内存是另一回事,因为读取或写入内存的成本通常与所使用的内存量呈线性关系(并且可能仅涉及对内存的硬件访问,也可能涉及进一步的操作系统干预,具体取决于具体情况) 。
分配使用
malloc
大致相同。核算会比仅仅更改堆栈指针更复杂,但它基本上仍然只是以较低的开销时间检查和更新一些数据结构,与分配的空间量不成正比。char buf[ N ]
未buf
初始化,即其所有元素都有未确定的值。因此,在所有三个测试用例中,您实际上并没有初始化数组,而只是分配内存。要查看实际差异,请添加大括号以对数组进行零初始化,如下所示:
现在您可以看到这个修改后的演示的不同之处。