【问题标题】:Performance of allocaalloca的性能
【发布时间】:2021-01-05 20:18:06
【问题描述】:

这些天我经常使用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 非常危险。宁愿只将它用于非常少量的数据。
  • 还要检查和比较编译器为这两种情况生成的代码。
  • 哦,请记住在启用优化后进行所有基准测试、测量或组装比较。

标签: c++ performance stack alloca


【解决方案1】:

allocamalloc 更快,原因与执行分配/解除分配的方式以及使用的内存部分有关,我相信你知道。正如 cmets 所述,它也很容易出错。

说到点子上,我的猜测是第一个版本,重复alloca,在未优化的设置中会比使用间接更快,事实上,在一些基准测试之后,这一点得到了证实:

测试是使用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 otpimization 后,正如人们所料,测试结果将趋于平衡,多个alloca 仍然始终稍快一些,但性能差异可以忽略不计。正如你所说,它基本上是一样的。使用其中一个似乎没有什么区别。

免责声明:

为了更好地了解您的程序的性能,与此处所做的孤立测试相比,集成测试可以为您提供更准确的读数。构建工具和环境也会影响最终结果,要全面准确地衡量您的选项的性能,您必须自己测试它们。

【讨论】:

    【解决方案2】:

    alloca 的用处在于,如果您事先不知道数组的大小。

    对于给定的代码,和简单的写法没什么区别:

    float array1[4096];
    float array2[4096];
    float array3[4096];
    float array4[4096];
    

    坦率地说,我认为没有必要进行基准测试; alloca 只是颠簸一个堆栈指针来为您的分配腾出空间,就像这些数组的声明一样。

    【讨论】:

    • 当然可以,但我之前不知道大小,示例只是为了演示情况。
    猜你喜欢
    • 2010-10-17
    • 2012-02-27
    • 2015-09-30
    • 2023-03-18
    • 2016-12-02
    • 2015-12-22
    • 2010-09-21
    • 2022-01-04
    • 2014-02-27
    相关资源
    最近更新 更多