标签: compiler-optimization

C++复制构造函数,临时函数和复制语义

对于这个计划

#include <iostream>
using std::cout;

struct C 
{
    C() { cout << "Default C called!\n"; }
    C(const C &rhs) { cout << "CC called!\n"; }
};

const C f()
{
    cout << "Entered f()!\n";
    return C();
}

int main()
{
    C a = f();
    C b = a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

Entered f()!
Default C called!
CC called!
Run Code Online (Sandbox Code Playgroud)

由于f()按值返回,它应该返回一个临时值.由于T a = x;T a(x);,是不是要求建设的拷贝构造函数a,使用临时传入作为它的参数?

c++ variable-assignment copy-constructor compiler-optimization temporaries

17
推荐指数
1
解决办法
1422
查看次数

Python是否优化了循环中的函数调用?

说,我有一个代码,从循环中调用一些函数数百万次,我希望代码快:

def outer_function(file):
    for line in file:
        inner_function(line)

def inner_function(line):
    # do something
    pass
Run Code Online (Sandbox Code Playgroud)

它不一定是文件处理,它可以是例如从函数绘制线调用的函数绘制点.这个想法是逻辑上这两者必须分开,但从性能的角度来看,它们应该尽可能快地一起行动.

Python会自动检测并优化这些内容吗?如果没有 - 有没有办法给它一个线索呢?可能使用一些额外的外部优化器?...

python optimization compiler-optimization

17
推荐指数
3
解决办法
3603
查看次数

(如何)Java JIT编译器优化我的代码?

我正在编写相当低级别的代码,必须对速度进行高度优化.每个CPU周期都很重要.因为代码是用Java编写的,所以我不能像C中那样写低级别,但是我希望能够从VM中获取所有内容.

我正在处理一个字节数组.我的代码有两个部分,我现在主要感兴趣.第一个是:

int key =  (data[i]     & 0xff)
        | ((data[i + 1] & 0xff) <<  8)
        | ((data[i + 2] & 0xff) << 16)
        | ((data[i + 3] & 0xff) << 24);
Run Code Online (Sandbox Code Playgroud)

第二个是:

key = (key << 15) | (key >>> 17);
Run Code Online (Sandbox Code Playgroud)

从性能来看,我猜这些陈述没有按照我的预期进行优化.第二个陈述基本上是一个ROTL 15, key.第一个语句将4个字节加载到int中.0xff如果访问的字节恰好为负,则掩码仅用于补偿由隐式转换为int所产生的添加符号位.这应该很容易转换为高效的机器代码,但令我惊讶的是,如果我删除了掩码,性能会上升.(这当然会破坏我的代码,但我很想知道会发生什么.)

这里发生了什么?最常见的Java VM是否会在JIT期间以期望优秀的C++编译器优化等效C++代码的方式优化此代码?我可以影响这个过程吗?设置-XX:+AggressiveOpts似乎没有区别.

(CPU:x64,平台:Linux/HotSpot)

java jit compiler-optimization

17
推荐指数
2
解决办法
3409
查看次数

基准测试,代码重新排序,易失性

我决定要对特定函数进行基准测试,所以我天真地编写如下代码:

#include <ctime>
#include <iostream>

int SlowCalculation(int input) { ... }

int main() {
    std::cout << "Benchmark running..." << std::endl;
    std::clock_t start = std::clock();
    int answer = SlowCalculation(42);
    std::clock_t stop = std::clock();
    double delta = (stop - start) * 1.0 / CLOCKS_PER_SEC;
    std::cout << "Benchmark took " << delta << " seconds, and the answer was "
              << answer << '.' << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

一位同事指出,我应该声明startstop变量volatile以避免代码重新排序.他建议优化器可以,例如,有效地重新排序代码,如下所示:

    std::clock_t start = std::clock();
    std::clock_t stop = …
Run Code Online (Sandbox Code Playgroud)

c++ benchmarking volatile compiler-optimization

17
推荐指数
1
解决办法
4121
查看次数

为什么编译器会生成此程序集?

在逐步执行一些Qt代码时,我遇到了以下内容.该函数QMainWindowLayout::invalidate()具有以下实现:

void QMainWindowLayout::invalidate()
{
QLayout::invalidate()
minSize = szHint = QSize();
}
Run Code Online (Sandbox Code Playgroud)

它被编译为:

<invalidate()>        push   %rbx
<invalidate()+1>      mov    %rdi,%rbx
<invalidate()+4>      callq  0x7ffff4fd9090 <QLayout::invalidate()>
<invalidate()+9>      movl   $0xffffffff,0x564(%rbx)
<invalidate()+19>     movl   $0xffffffff,0x568(%rbx)
<invalidate()+29>     mov    0x564(%rbx),%rax
<invalidate()+36>     mov    %rax,0x56c(%rbx)
<invalidate()+43>     pop    %rbx
<invalidate()+44>     retq
Run Code Online (Sandbox Code Playgroud)

从invalidate + 9到invalidate + 36的程序集似乎很愚蠢.首先,代码将-1写入%rbx + 0x564和%rbx + 0x568,但是然后它将-1从%rbx + 0x564加载回寄存器,只是将其写入%rbx + 0x56c.这似乎是编译器应该能够轻松优化到另一个立即行动的东西.

那么这个愚蠢的代码(如果是这样,为什么编译器不会对它进行优化?)或者这是否比使用另一个立即动作更聪明,更快?

(注意:此代码来自ubuntu提供的正常发布库版本,因此它可能是由GCC在优化模式下编译的.minSize而且szHint变量是类型的正常变量QSize.)

c++ assembly gcc compiler-optimization

17
推荐指数
2
解决办法
1085
查看次数

如何检查给定的数字是否能以最快的方式整除15?

处理器中的分区需要很长时间,所以我想问如何以最快的方式检查数字是否可以被其他数字整除,在我的情况下我需要检查数字是否可被15整除.

此外,我一直在浏览网页,并找到有趣的方法来检查数字是否可以被某些数字整除,但我正在寻找快速选项.

注意:由于分工需要很长时间,我正在寻找没有/和的答案%.

c c++ performance integer-division compiler-optimization

17
推荐指数
5
解决办法
3万
查看次数

对于采用 const 结构的函数,编译器不会优化函数体吗?

我有以下代码:

#include <stdio.h>

typedef struct {
    bool some_var;
} model_t;

const model_t model = {
    true
};

void bla(const model_t *m) {
    if (m->some_var) {
        printf("Some var is true!\n");
    }
    else {
        printf("Some var is false!\n");
    }
}

int main() {
    bla(&model);
}
Run Code Online (Sandbox Code Playgroud)

我想编译器拥有消除函数else中的子句所需的所有信息bla()。调用该函数的唯一代码路径来自 main,并且它接受const model_t,因此它应该能够确定该代码路径未被使用。然而:

不带内联

在 GCC 12.2 中,我们看到第二部分被链接进来。

如果我的inline功能这个消失了:

带内联

我在这里缺少什么?有什么方法可以让编译器做一些更智能的工作吗?在 C 和 C++ 中,使用-O3和都会发生这种情况-Os

c c++ gcc compiler-optimization

17
推荐指数
3
解决办法
2618
查看次数

2 个经过“restrict”修饰的指针可以比较相等吗?

int foo(void *restrict ptr1, void *restrict ptr2)
{
  if (ptr1 == ptr2) {
    return 1234;
  } else {
    return 4321;
  }
}
Run Code Online (Sandbox Code Playgroud)

restrict意味着指针指向的内存没有被任何其他指针别名。鉴于此,thenptr1ptr2不能指向同一区域,因此比较是同义反复,并且在所有情况下都foo()应该返回。4321

然而clanggcc不要这样看(https://godbolt.org/z/fvPd4a1vd)。这是错过的优化还是有其他原因?

c c++ compiler-optimization language-lawyer restrict-qualifier

17
推荐指数
2
解决办法
849
查看次数

由于未定义的行为或编译器错误导致C++代码崩溃?

我遇到了奇怪的崩溃.我想知道它是否是我的代码或编译器中的错误.当我使用Microsoft Visual Studio 2010将以下C++代码编译为优化的发布版本时,它会在标记的行中崩溃:

struct tup { int x; int y; };

class C 
{
public:
  struct tup* p;

  struct tup* operator--() { return --p; }
  struct tup* operator++(int) { return p++; }

  virtual void Reset() { p = 0;}
};

int main ()
{
  C c;
  volatile int x = 0;
  struct tup v1;
  struct tup v2 = {0, x};

  c.p = &v1;
  (*(c++)) = v2;

  struct tup i = (*(--c));   // crash! (dereferencing a NULL-pointer)
  return i.x;
} …
Run Code Online (Sandbox Code Playgroud)

c++ crash visual-studio-2010 compiler-optimization visual-c++

16
推荐指数
1
解决办法
714
查看次数

为什么启用未定义的行为清理会干扰优化?

考虑以下代码:

#include <string_view>

constexpr std::string_view f() { return "hello"; }

static constexpr std::string_view g() {
    auto x = f();
    return x.substr(1, 3);
}

int foo() { return g().length(); }
Run Code Online (Sandbox Code Playgroud)

如果我用 GCC 10.2 和 flags 编译它--std=c++17 -O1,我会得到:

foo():
        mov     eax, 3
        ret
Run Code Online (Sandbox Code Playgroud)

此外,据我所知,这段代码没有任何未定义的行为问题。

但是 - 如果我添加 flag -fsanitize=undefined,编译结果是:

.LC0:
        .string "hello"
foo():
        sub     rsp, 104
        mov     QWORD PTR [rsp+80], 5
        mov     QWORD PTR [rsp+16], 5
        mov     QWORD PTR [rsp+24], OFFSET FLAT:.LC0
        mov     QWORD PTR [rsp+8], 3
        mov     QWORD …
Run Code Online (Sandbox Code Playgroud)

c++ gcc compiler-optimization constexpr ubsan

16
推荐指数
2
解决办法
603
查看次数