我发现这个主题为什么处理排序数组比未排序数组更快?.并尝试运行此代码.而且我发现了奇怪的行为.如果我使用-O3优化标志编译此代码,则需要2.98605 sec运行.如果我用-O2它编译1.98093 sec.我尝试在同一环境中的同一台机器上运行此代码几次(5或6),我关闭所有其他软件(chrome,skype等).
gcc --version
gcc (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Run Code Online (Sandbox Code Playgroud)
那么请你能解释一下为什么会这样吗?我阅读gcc手册,我看到-O3包括-O2.谢谢你的帮助.
PS添加代码
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned …Run Code Online (Sandbox Code Playgroud) 是否有gcc编译指示或我可以用来强制gcc在特定代码段上生成无分支指令?
我有一段代码,我希望gcc使用cmov指令编译成无分支代码:
int foo(int *a, int n, int x) {
int i = 0, j = n;
while (i < n) {
#ifdef PREFETCH
__builtin_prefetch(a+16*i + 15);
#endif /* PREFETCH */
j = (x <= a[i]) ? i : j;
i = (x <= a[i]) ? 2*i + 1 : 2*i + 2;
}
return j;
}
Run Code Online (Sandbox Code Playgroud)
事实上,它确实如此:
morin@soprano$ gcc -O4 -S -c test.c -o -
.file "test.c"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
testl …Run Code Online (Sandbox Code Playgroud) 我对于在分支方面理论上掩蔽可以做什么感到困惑.假设我有一个Skylake-SP(哈,我希望......),我们忽略了编译器功能,理论上可能的是:
如果分支条件依赖于静态标志,并且所有分支都将数组设置为计算结果,假设编译器不将其优化为两个单独的循环,它是否可以向量化?
do i = 1, nx
if (my_flag .eq. 0) then
a(i) = b(i) ** 2
else
a(i) = b(i) ** 3
end if
end do
Run Code Online (Sandbox Code Playgroud)
如果仅作为分支的子集设置有问题的值,它可以矢量化吗?
do i = 1, nx
if (my_flag .eq. 0) then
a(i) = b(i) ** 2
end if
end do
Run Code Online (Sandbox Code Playgroud)
如果分支条件本身依赖于矢量数据,它可以矢量化吗?
do i = 1, nx
if (c(i) > 0) then
a(i) = b(i) ** 2
else
a(i) = b(i) ** 3
end if
end do
Run Code Online (Sandbox Code Playgroud) 我想知道是否有办法在 gcc/g++ 中禁用预测。当我获得代码的对象转储时,我不希望其中包含任何 CMOV、CCMP 等指令。
我已经浏览了 gcc 手册页,但没有任何成功。到目前为止,唯一的出路似乎是侵入 gcc 本身。在 RHEL x86_64 机器上使用 gcc 4.3。有任何想法吗?
提前致谢。
我试图用三元运算符的语义引入泛型函数:E1 ? E2 : E3.我看到编译器能够消除三元运算符之一E2或E3取决于E1条件的计算.然而,GCC在ternary函数调用的情况下错过了这种优化(即使E2/ E3没有副作用).
在下面的清单中ternary,写入函数的行为类似于三元运算符.然而,GCC发出可能对函数的大量调用,f这似乎可以消除某些输入值(确切地说它是如何为三元运算符完成的)因为f使用纯属性声明 - 请查看GCC生成的汇编代码的godbolt链接.
它是否可以在GCC(优化空间)中得到改进,或者C++标准是否明确禁止这种优化?
// Very heavy function
int f() __attribute__ ((pure));
inline int ternary(bool cond, int n1, int n2) {
return cond ? n1 : n2;
}
int foo1(int i) {
return i == 0 ? f() : 0;
}
int foo2(int i) {
return ternary(i == 0, f(), 0);
}
Run Code Online (Sandbox Code Playgroud)
装配清单-O3 -std=c++11 …
我注意到条件移动指令的可扩展性比普通的mov. 例如,它不支持立即数,也不支持寄存器的低字节。
出于好奇,为什么该Cmov命令比一般mov命令的限制性要大得多?例如,为什么两者不允许这样的事情:
mov $2, %rbx # allowed
cmovcc $1, %rbx # I suppose setcc %bl could be used for the '1' immediate case
Run Code Online (Sandbox Code Playgroud)
附带说明一下,我注意到在使用 Compiler Explorer 时, 的使用量比和cmovcc少得多。通常是这种情况吗?如果是,为什么它的使用频率低于其他条件句?jmpccsetcc
我有这个简单的二进制搜索成员函数,在那里lastIndex,nIter并且xi是类成员:
uint32 scalar(float z) const
{
uint32 lo = 0;
uint32 hi = lastIndex;
uint32 n = nIter;
while (n--) {
int mid = (hi + lo) >> 1;
// defining this if-else assignment as below cause VS2015
// to generate two cmov instructions instead of a branch
if( z < xi[mid] )
hi = mid;
if ( !(z < xi[mid]) )
lo = mid;
}
return lo;
}
Run Code Online (Sandbox Code Playgroud)
gcc和VS 2015都将内循环转换为代码流分支:
000000013F0AA778 movss xmm0,dword …Run Code Online (Sandbox Code Playgroud) gcc ×5
assembly ×3
c++ ×3
optimization ×3
x86 ×3
avx512 ×1
c ×1
fortran ×1
instructions ×1
simd ×1