使用内部静态变量来提高性能?

时间:2009-09-29 11:24:23

标签: c

我有一个函数需要相当多的内部临时存储来进行计算(一些矩阵运算),我知道这个函数会被频繁调用(比如整个程序运行时的每毫秒)。我的直觉告诉我,最好将这些临时变量声明为静态,因此每次调用函数时都不会再次创建它们。每次调用函数时我都必须初始化它们,因此功能目的不需要保持它们存活。我知道让它们静态会破坏线程安全性,但这不是问题。

由于知识通常比任何直觉都好,我想知道处理这种情况的“正确”方法是什么。

void frequentlyCalledFunction(void)
{
    double matrix1[10][10];
    double matrix2[10][10];
    /* do something with the matrices ... */
}

void frequentlyCalledFunction(void)
{
    static double matrix1[10][10];
    static double matrix2[10][10];
    /* do something with the matrices ... */
}

8 个答案:

答案 0 :(得分:16)

没有区别。 “创建”未初始化的数组不需要代码。

对于静态数组,内存保留并始终可用。在自动数组的情况下,它位于堆栈上,“创建”它所需要的就是移动堆栈指针,这在进入函数时无论如何都会发生。

(有一天你会尝试在多线程程序中使用该功能,静态版本会偶尔出现间歇性故障,导致你喝酒和吸毒。这不值得冒风险。)

答案 1 :(得分:9)

我绝对会先用最简单,最易阅读的方式写出来。每毫秒听起来像一个非常很少运行的函数进行微优化。

一旦你有了它,就可以对它进行基准测试。确定性能是否足够好。如果不是,请再次进行优化和基准测试。 如果没有非常可靠的数字,不要弯曲干净的代码,以支持您的决定。

答案 2 :(得分:5)

像往常一样,你应该先进行剖析。局部变量可能只会导致堆栈指针递减一点,不应该有任何性能损失。

答案 3 :(得分:2)

您正在尝试进行微观优化而不进行基准测试,这通常被认为是一件坏事。你应该总是基准。否则,您如何确定任何优化尝试都有效?

您不可能从中获得任何收益,并且应该首先提供代码可读性和可维护性。

答案 4 :(得分:2)

分配堆栈变量与分配堆变量不同,所有发生的事情都是堆栈指针向下移动到足以分配函数所需的所有内存。在堆栈帧中分配一个或一百个变量没有任何开销。即使零变量(记录返回的位置等),在调用函数时,堆栈指针也将被移动。

答案 5 :(得分:1)

要知道的唯一方法是尝试并测试它。但是,这不太可能产生太大的影响。

答案 6 :(得分:1)

在SPARC上,特别是在64位模式下,静态情况较慢。访问一个全局变量(静态是,它只是限制在函数范围内的名称)需要5个指令使用3个寄存器,在你的情况下10个指令只能获取数组的地址。正如已经指出的那样,非静态版本没有开销,因为框架是以任何形式构建的,如果堆栈指针增长16个字节或200个没有区别。 但是如果你初始化你的数组,要小心,这可能会产生一个隐藏的memset,这可能是昂贵的。

void frequentlyCalledFunction(void)
{
  double matrix1[10][10]={0.0};
  double matrix2[10][10]={0.0};
  /* do something with the matrices ... */
}

可能会进行1或2次memcpy或memset调用来初始化数组。

答案 7 :(得分:0)

为具有自动存储持续时间的变量保留空间意味着只减少堆栈指针,因此只要这些不是唯一的局部变量,就没有开销。

可能会影响性能的是,堆栈分配的变量必须相对于堆栈或基址指针进行寻址,因此使用static可能会略微提高性能。

与往常一样,对代码进行基准测试以确保。