对于这个计划
#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
说,我有一个代码,从循环中调用一些函数数百万次,我希望代码快:
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会自动检测并优化这些内容吗?如果没有 - 有没有办法给它一个线索呢?可能使用一些额外的外部优化器?...
我正在编写相当低级别的代码,必须对速度进行高度优化.每个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)
我决定要对特定函数进行基准测试,所以我天真地编写如下代码:
#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)
一位同事指出,我应该声明start和stop变量volatile以避免代码重新排序.他建议优化器可以,例如,有效地重新排序代码,如下所示:
std::clock_t start = std::clock();
std::clock_t stop = …Run Code Online (Sandbox Code Playgroud) 在逐步执行一些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.)
处理器中的分区需要很长时间,所以我想问如何以最快的方式检查数字是否可以被其他数字整除,在我的情况下我需要检查数字是否可被15整除.
此外,我一直在浏览网页,并找到有趣的方法来检查数字是否可以被某些数字整除,但我正在寻找快速选项.
注意:由于分工需要很长时间,我正在寻找没有/和的答案%.
我有以下代码:
#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。
int foo(void *restrict ptr1, void *restrict ptr2)
{
if (ptr1 == ptr2) {
return 1234;
} else {
return 4321;
}
}
Run Code Online (Sandbox Code Playgroud)
restrict意味着指针指向的内存没有被任何其他指针别名。鉴于此,thenptr1和ptr2不能指向同一区域,因此比较是同义反复,并且在所有情况下都foo()应该返回。4321
然而clang,gcc不要这样看(https://godbolt.org/z/fvPd4a1vd)。这是错过的优化还是有其他原因?
c c++ compiler-optimization language-lawyer restrict-qualifier
我遇到了奇怪的崩溃.我想知道它是否是我的代码或编译器中的错误.当我使用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++
考虑以下代码:
#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++ ×8
c ×3
gcc ×3
assembly ×1
benchmarking ×1
constexpr ×1
crash ×1
java ×1
jit ×1
optimization ×1
performance ×1
python ×1
temporaries ×1
ubsan ×1
visual-c++ ×1
volatile ×1