微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – 为什么我必须打开g中的优化以进行简单的阵列访问?

我用C( gcc / Linux)中的双精度std :: vector写了一个简单的高斯消元算法.现在我已经看到运行时依赖于编译器的优化级别(使用-O3时速度提高了5倍).我写了一个小测试程序并收到了类似的结果.问题不在于矢量的分配,也没有任何调整大小等.

陈述这是一个简单的事实:

v[i] = x + y / z;

(或类似的东西)没有优化就慢得多.我认为问题是索引运算符.如果没有编译器优化,std :: vector比raw double * v慢,但是当我打开优化时,性能是相同的,令我惊讶的是,即使访问raw double * v也更快.

这种行为有解释吗?我真的不是一个专业的开发人员,但我认为编译器应该能够将上述语句直接转移到硬件指令.为什么需要启用优化,更重要的是,优化的缺点是什么? (如果没有,我想知道为什么优化不是标准.)

这是我的矢量测试代码

const long int count = 100000;
const double pi = 3.1416;
void C_array (long int size)
{
  long int start = time(0);
  double *x = (double*) malloc (size * sizeof(double));
  for (long int n = 0; n < count; n++)
    for (long int i = 0; i < size; i++)
      x[i] = i;
      //x[i] = pi * (i-n);
  printf ("C array   : %li s\n",time(0) - start);
  free (x);
}

void CPP_vector (long int size)
{
  long int start = time(0);
  std::vector<double> x(size);
  for (long int n = 0; n < count; n++)
    for (long int i = 0; i < size; i++)
      x[i] = i;
      //x[i] = pi * (i-n);
  printf ("C++ vector: %li s\n",time(0) - start);
}

int main ()
{
  printf ("Size of vector: ");
  long int size;
  scanf ("%li",&size);

  C_array (size);
  CPP_vector (size);
  return 0;
}

我收到了一些奇怪的结果.标准g编译为矢量大小为20 000生成运行时8 s(C数组)或18 s(std :: vector).如果我使用//后面更复杂的行,则运行时为8/15 s(是的,更快).如果我打开-O3那么,对于40,000矢量大小,运行时间为5/5秒.

解决方法

为什么我们需要优化/调试版本?

优化可以完全重新排序指令序列,消除变量,内联函数调用,并使可执行代码远离您无法调试的源代码.因此,不使用优化的原因之一是保持调试代码的可能性.当您的代码(当您相信您的代码时)完全调试时,您可以打开优化以生成发布版本.

为什么调试代码慢?

>要记住的一件事是,STL的调试版本可能包含对迭代器的边界和有效性的附加检查.这可能会使代码速度减慢10倍.这已知是Visual C STL的一个问题,但在您的情况下,您没有使用它.我不知道gcc的STL的艺术状况.
>另一种可能性是您以非线性顺序访问内存,产生大量缓存未命中.在调试模式下,编译器将重新生成代码生成此低效代码.但是当启用优化时,它可能会将您的访问重写为顺序访问,而不会产生任何缓存未命中.

该怎么办 ?

您可以尝试展示一个展示行为的简单可编辑示例.然后我们可以编译并查看程序集来解释实际情况.如果遇到缓存问题,您正在处理的数据大小很重要.

链接

> Visual C STL在调试模式下运行缓慢:http://marknelson.us/2011/11/28/vc-10-hash-table-performance-problems/
> STL的调试版本与Visual C:http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Advanced-STL/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-3-of-n有什么关系?
>缓存未命中及其影响:http://channel9.msdn.com/Events/Build/2014/2-661,特别是29’27“
>再次缓存:https://www.youtube.com/watch?v=fHNmRkzxHWs at 36’34“

原文地址:https://www.jb51.cc/c/119044.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐