【问题标题】:Rarely used function that is unused affecting the performance很少使用的功能,未使用会影响性能
【发布时间】:2021-09-15 21:06:09
【问题描述】:

程序中有一个基本功能很少用到。但是,我发现即使在特定的执行中不使用这个函数,这个函数也会导致运行时开销的增加。

详细解释...

下面的代码是我最好的尝试写一个最小的例子来说明我的意思,但如果它没有意义,我提前道歉。我正在使用 C 语言的最小空间工作,所以如果代码看起来没有优化,那是因为我别无选择:((当然,我非常愿意接受任何建议)

// extra_function.c
int extra_array[6] = {0, 1, 2, 3, 4, 5}
void copy_array(int *array, int num) {
  switch (num) {
  case (0):
    for(int i = 0; i < 6; ++i)
            array[i] = extra_array[i];
            break;
  }
}
// main.c
#include "extra_function.c"
int main(int argc, char *argv[]) {
  int target_array[10] = {0};
  int copy_check = 0;
  if (argc == 2) {
    copy_check = 1;
  }

  // high runtime overhead
  if (copy_check == 1) {
    copy_array (target_array, 0);
  }

  // never used
  if (false) {
    copy_array (target_array, 0);
  }
}

总而言之,基本上,我需要使用在main.c 之外实例化的函数copy_array 将静态分配的数组从extra_function.c 复制到main.c

main.c 来看,argc == 2 必须发生条件 copy_check 变量才能变为 1,否则永远不会调用 copy_array 函数。

在我的场景中,argc == 2 条件永远不会发生

但是,似乎因为argc == 2 条件可能发生的可能性,运行时开销会增加,即使这种情况永远不会发生。

为什么会发生这种情况?是不是因为即使在此执行中可能永远不会调用函数,但在下面进行了某种初始化会导致运行时开销?

我之所以能够发现这一点,是因为通过使该函数不被使用(如// never used 所示),我能够节省运行时开销。

如果我的问题不清楚,请告诉我,我知道这个问题可能听起来很荒谬,但我一直试图弄清楚为什么会发生这种情况,但无济于事。

这是一个类似的问题:Unused function changes performances,但这似乎只是关于未使用的功能,而我的问题是关于很少使用的功能未使用

感谢您提供的任何帮助。

【问题讨论】:

  • "在我的场景中,argc == 2 条件永远不会发生。"不清楚。代码中没有任何内容禁止这样做。编译器不知道argc == 2 永远不会发生。
  • "argc == 2 条件永远不会发生。" - 编译器不可能做出这个断言。如果这样做是不正确的。
  • if (false) 的情况下,编译器可以证明copy_array 从未在main 中使用,因此target_array 是未使用的变量,因此可以消除整个数组。在argc 版本中,编译器无法证明任何事情,因此它必须分配一个数组。如果数组在你的“真实”程序中明显更大,那么与可以完全省略数组的版本相比,这会带来很大的开销。
  • 什么样的运行时开销(空间、执行时间等)?与没有它相比,这会导致多少额外开销?
  • 造成开销的原因是什么?初始化还是内存分配?如果未使用 target_array,您可以跳过初始化 e.i 使用 int target_array[10]; 而不是 int target_array[10] = {0};

标签: c performance gcc optimization


【解决方案1】:

是不是因为即使一个函数可能永远不会在 this 中被调用 执行,在其下进行了某种初始化 导致运行时开销?

运行时开销是由target_array 的初始化引起的。如果不使用target_array,您可以跳过它的初始化,例如我使用int target_array[10]; 而不是int target_array[10] = {0};

如果target_array 在您的“真实”程序中分配在堆上,您可以只定义一个指针并在需要时在copy_array 中进行内存分配。只定义一个指针int* target_array=nullptr;绝对不会造成开销。

【讨论】:

  • @Jay 我已将我的 cmets 复制到一个答案中,请接受它,其他人可以看到您的问题已解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2010-09-30
相关资源
最近更新 更多