c++ - alloca的性能
问题描述
这些天我使用alloca
了很多来分配临时缓冲区。在我的应用程序(信号处理)中,这是一个常见的需求。
问题是:
分配多个数组时,只使用一次 alloca 会更好(性能方面)吗?
像这样:
float *array1 = (float*)alloca(4096 * 4);
float *array2 = array1 + 1024;
float *array3 = array2 + 1024;
float *array4 = array3 + 1024;
或者像这样多次使用它:
void *array1 = (float*)alloca(4096);
void *array2 = (float*)alloca(4096);
void *array3 = (float*)alloca(4096);
void *array4 = (float*)alloca(4096);
我的意思是它可能所做的只是减少堆栈指针并可能执行“堆栈探测”,这取决于大小,所以可能没关系?
解决方案
alloca
malloc
正如我确定您知道的那样,由于与执行分配/解除分配的方式以及使用的内存部分相关的原因,它的速度更快。正如评论中所述,它也很容易出错。
就这一点而言,我的猜测是alloca
,在未优化的设置中,第一个版本 repeating 会比玩间接更快,事实上,在一些基准测试之后,这一点得到了证实:
测试是使用google benchmark、clang 10.0、C++20 std 进行的,没有优化。使用类似于 OP 代码的函数运行重复测试并获得恒定结果:
#include <alloca.h>
void alloc1(){
float *array1 = (float*)alloca(4096 * 4);
float *array2 = array1 + 1024;
float *array3 = array2 + 1024;
float *array4 = array3 + 1024;
}
void alloc2(){
void *array1 = (float*)alloca(4096);
void *array2 = (float*)alloca(4096);
void *array3 = (float*)alloca(4096);
void *array4 = (float*)alloca(4096);
}
static void alloca1_test(benchmark::State& state) {
for (auto _ : state) {
alloc1();
//benchmark::DoNotOptimize();
}
}
BENCHMARK(alloca1_test);
static void alloca2_test(benchmark::State& state) {
for (auto _ : state) {
alloc2();
//benchmark::DoNotOptimize();
}
}
BENCHMARK(alloca2_test);
正如O3
人们所期望的那样,添加了优化后,测试结果将趋于平衡,倍数alloca
仍然始终稍快一些,但性能差异可以忽略不计。正如你所说,它基本上是一样的。使用其中一个似乎没有什么区别。
免责声明:
为了更好地了解您的程序的性能,集成测试会给您比这里所做的孤立测试更准确的读数。构建工具和环境也会影响最终结果,要全面准确地衡量您的选项的性能,您必须自己测试它们。
推荐阅读
- javascript - 数组对象文件表单数据
- python - Matplotlib 绘制数百个矩形轮廓
- java - 如何在不考虑循环大小的情况下运行 For 循环最长 60 秒并完成所有迭代
- javascript - 在此 switch 语句中执行 `return '';` 或 `return null;` 是否更有意义?
- java - 未找到带有 maven 和 SQL Server 类的微服务异常
- excel - 如何使用用户输入的文件名导出 excel 文件?
- php - 如何编写查询以从 laravel 中的数据透视表中获取特定数据?
- node.js - 认证后环回 4 错误。键“authentication.currentUser”未绑定到上下文应用程序中的任何值
- go - 实现梯度下降
- azure - Azure 函数运行时异常,系统数据 sqlclient 异常的类型初始化程序,无法加载 DLL 'sni.dll'