标签: compiler-optimization

为什么编译器不将浮点*2优化为指数增量?

我经常注意到gcc将乘法转换为可执行文件中的移位.当乘以a int和a 时,可能会发生类似的事情float.例如,2 * f可能只是将指数递增f1,从而节省了一些周期.编译器,也许是一个人请求他们这样做(例如通过-ffast-math),一般来说,这样做吗?

编译器通常是否足够聪明,或者我是否需要使用scalb*()ldexp()/frexp()函数系列自己完成此操作?

c c++ optimization performance compiler-optimization

46
推荐指数
4
解决办法
3844
查看次数

冗余演员表会得到优化吗?

我正在更新一些旧代码,并且发现了几个实例,每次需要调用其中一个属性或方法时,都会重复转换相同的对象.例:

if (recDate != null && recDate > ((System.Windows.Forms.DateTimePicker)ctrl).MinDate)
{
    ((System.Windows.Forms.DateTimePicker)ctrl).CustomFormat = "MM/dd/yyyy";
    ((System.Windows.Forms.DateTimePicker)ctrl).Value = recDate;
}
else
{
    (System.Windows.Forms.DateTimePicker)ctrl).CustomFormat = " ";
}
((System.Windows.Forms.DateTimePicker)ctrl).Format = DateTimePickerFormat.Custom;
Run Code Online (Sandbox Code Playgroud)

我倾向于修复这种怪异,但考虑到我有限的时间,我不想打扰任何不影响功能或性能的东西.

所以我想知道的是,这些冗余的演员是否被编译器优化了?我试着用一个简单的例子使用ildasm自己搞清楚,但不熟悉IL我只是更加困惑.

UPDATE

到目前为止,共识似乎是a)不,演员表没有优化,但b)虽然可能会有一些小的性能影响因此,它不太可能显着,并且c)我应该考虑修复它们无论如何.如果我有时间的话,我有一天会解决这些问题.同时,我不会担心他们.

感谢大家!

.net c# jit casting compiler-optimization

45
推荐指数
3
解决办法
1854
查看次数

当C++将元素从函数的返回值存储到std :: vector时出现意外的结果

当函数涉及重新分配时,我发现一些编译器可能在函数调用之前保存地址.它导致存储在无效地址中的返回值.

在上面的描述中有一个例子来解释行为.

#include <stdio.h>
#include <vector> 
using namespace std;

vector<int> A; 
int func() { 
    A.push_back(3);
    A.push_back(4);
    return 5; 
} 
int main() { 
    A.reserve(2);
    A.push_back(0);
    A.push_back(1);
    A[1] = func();
    printf("%d\n", A[1]);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有一些常见的C++编译器,测试结果如下.

  • GCC(GNU编译器集合):运行时错误或输出 1
  • Clang:输出 5
  • VC++:输出 5

是不确定的行为?

c++ gcc vector compiler-optimization compiler-bug

45
推荐指数
1
解决办法
1866
查看次数

仅在启用编译优化时发生错误

我遇到了代码中的错误,只有在启用了优化的情况下构建代码时才会重现.我制作了一个控制台应用程序来复制测试逻辑(下面的代码).你会看到,当启用优化时,'value'在执行这个无效逻辑后变为null:

if ((value == null || value == new string[0]) == false)
Run Code Online (Sandbox Code Playgroud)

修复是直截了当的,并在违规代码下方注释掉.但是......我更担心的是我可能遇到了汇编程序中的错误,或者其他人可能会解释为什么将值设置为null.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace memory_testing
{
    class Program
    {
        sta tic void Main(string[] args)
        {
            while(true)
            {
                Console.Write("Press any key to start...");
                Console.ReadKey();
                Console.WriteLine();
                PrintManagerUser c = new PrintManagerUser();
                c.MyProperty = new string[1];
            }
        }
    }

    public class PrintManager
    {
        public void Print(string key, object value)
        {
            Console.WriteLine("Key is: " + key);
            Console.WriteLine("Value is: " + value);
        }
    }

    public class PrintManagerUser …
Run Code Online (Sandbox Code Playgroud)

c# compiler-optimization

44
推荐指数
1
解决办法
2608
查看次数

不同的优化级别可以导致功能不同的代码吗?

我很好奇编译器在优化时的自由度.让我们将这个问题限制在GCC和C/C++(任何版本,任何标准版本):

是否有可能根据编译的优化级别编写行为不同的代码?

我想到的例子是在C++中的各种构造函数中打印不同的文本位,并根据副本是否被删除而获得差异(尽管我无法使这样的东西工作).

不允许计数时钟周期.如果你有一个非GCC编译器的例子,我也很好奇,但我无法检查它.C中的示例的奖励积分:-)

编辑:示例代码应该是标准兼容的,并且从一开始就不包含未定义的行为.

编辑2:已经有了一些很棒的答案!让我稍微了解一下:代码必须构成一个格式良好的程序并且符合标准,并且必须在每个优化级别编译为正确的,确定性的程序.(这不包括形状不规则的多线程代码中的竞争条件等.)我也理解浮点舍入可能会受到影响,但让我们对此进行折扣.

我只获得了800点声望,所以我认为我将在第一个完整的例子中赢得50点声望以符合这些条件的(精神); 25如果涉及滥用严格别名.(视某人向我展示如何向他人发送赏金.)

c c++ gcc compiler-optimization

44
推荐指数
6
解决办法
4456
查看次数

在C/C++中使用汇编语言

我记得在某处可以真正优化和加速代码的某些部分,程序员用汇编语言编写该部分.我的问题是 -

  1. 这种做法还在做吗?一个人怎么做?
  2. 不是用汇编语言编写有点过于繁琐和陈旧吗?
  3. 当我们编译C代码(带或不带-O3标志)时,编译器会进行一些代码优化并链接所有库并将代码转换为二进制对象文件.因此,当我们运行程序时,它已经处于最基本的形式,即二进制.那么如何诱导'汇编语言'有帮助?

我正在努力理解这个概念,非常感谢任何帮助或链接.

更新:根据dbemerlin的要求改写第3点 - 因为您可能能够编写比编译器生成的更有效的汇编代码,但除非您是汇编专家,否则您的代码运行速度会慢,因为编译器通常会比大多数人更好地优化代码.

c c++ optimization assembly compiler-optimization

43
推荐指数
4
解决办法
1万
查看次数

"xor eax,ebp"用于C++编译器输出

我只是尝试在VS2010上编译几个C++片段并分析IDA Pro上的可执行文件.我注意到的是,他们中的大多数在开始时都有类似的内容(在调用__security_check_cookie之后不久)

xor eax, ebp

和类似的东西

xor ecx, ebp

在底部.为什么会这样?编译器优化已关闭.

c++ assembly reverse-engineering buffer-overflow compiler-optimization

43
推荐指数
1
解决办法
4444
查看次数

拥有大量小方法是否有助于JIT编译器进行优化?

在最近关于如何优化某些代码的讨论中,我被告知将代码分解为许多小方法可以显着提高性能,因为JIT编译器不喜欢优化大型方法.

我不确定这一点,因为看起来JIT编译器本身应该能够识别自包含的代码段,而不管它们是否在他们自己的方法中.

任何人都可以确认或驳斥这一说法吗?

java optimization jit compiler-optimization

42
推荐指数
3
解决办法
3399
查看次数

反向迭代器在优化时返回垃圾

我有一个AsIterator模板类,它采用类似数字的类型,在这个例子中只是一个int,并将其转换为迭代器(++--递增和递减数字,并operator*只返回对它的引用).

这工作正常,除非它被包装成a std::reverse_iterator并使用任何优化编译(-O足够).当我优化二进制文件时,编译器去除reverse_iterator对它的取消引用调用,并用一些奇怪的值替换它.必须注意的是,它仍然可以进行正确的迭代次数.它只是反向迭代器获得的值,即垃圾.

请考虑以下代码:

#include <iterator>
#include <cstdio>

template<typename T>
class AsIterator : public std::iterator<std::bidirectional_iterator_tag, T> {
    T v;
public:
    AsIterator(const T & init) : v(init) {}

    T &operator*() { return v; }

    AsIterator &operator++() { ++v; return *this; }
    AsIterator operator++(int) { AsIterator copy(*this); ++(*this); return copy; }
    AsIterator &operator--() { --v; return *this; }
    AsIterator operator--(int) { AsIterator copy(*this); …
Run Code Online (Sandbox Code Playgroud)

c++ reverse iterator loops compiler-optimization

42
推荐指数
1
解决办法
1593
查看次数

为什么 switch 没有像 c/c++ 中的 if else 链式优化那样进行优化?

下面的 square 实现会产生一系列 cmp/je 语句,就像我期望的链式 if 语句一样:

int square(int num) {
    if (num == 0){
        return 0;
    } else if (num == 1){
        return 1;
    } else if (num == 2){
        return 4;
    } else if (num == 3){
        return 9;
    } else if (num == 4){
        return 16;
    } else if (num == 5){
        return 25;
    } else if (num == 6){
        return 36;
    } else if (num == 7){
        return 49;
    } else {
        return num * num; …
Run Code Online (Sandbox Code Playgroud)

c c++ optimization gcc compiler-optimization

42
推荐指数
2
解决办法
2720
查看次数