Tag: 编译器优化

是否存在导致50%分支预测未命中的代码?

问题: 我试图找出如何编写代码(C优先,仅在没有其他解决方案的情况下 ASM),这将使分支预测在50%的情况下失败 。 所以它必须是一段代码“对于与分支相关的编译器优化”是“imune”的,并且所有HW分支预测都不应该优于50%(掷硬币)。 即使是更大的挑战,也能够在多个CPU架构上运行代码并获得相同的50%缺失率。 我设法编写了一个在x86平台上达到47%分支未命中率的代码。 我怀疑失踪可能有3%来自: 已经分支的程序启动开销(尽管很小) Profiler开销 – 基本上对于每个计数器读取都会引发中断,因此可能会添加其他可预测的分支。 在后台运行的系统调用包含循环和可预测的分支 我编写了自己的随机数生成器,以避免调用rand,其实现可能隐藏了可预测的分支。 当可用时它也可以使用rdrand 。 延迟对我来说无关紧要。 问题: 我能比我的代码版做得更好吗? 更好的意思是为所有CPU架构获得更高的分支错误预测和相同的结果。 这段代码可以预测吗? 那是什么意思? 代码: #include #include #define RDRAND #define LCG_A 1103515245 #define LCG_C 22345 #define LCG_M 2147483648 #define ULL64 unsigned long long ULL64 generated; ULL64 rand_lcg(ULL64 seed) { #ifdef RDRAND ULL64 result = 0; asm volatile […]

关于c中“非法”的优化?

在学习编译器优化时,我在Linux下使用GCC版本gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5.1)编写代码 为了理解C中not a statement (nop),我先写了两个代码,然后使用gcc -S选项generate their compiled assembly code 。 拳头代码yc desktop:~$ cat yc main() { int i=0; } desktop:~$ gcc -S yc desktop:~$ 第二个代码xc desktop:~$ cat xc main() { int i=0; /* Loops and if*/ while(0); for(;0;); if(0); /* Arithmetic Operations */ i * i; i / i; i […]

编译器会优化静态函数的未使用参数吗?

我有一组函数都声明为static和fastcall 。 他们中的大多数都使用指向结构的指针,该结构在C ++中或多或少地扮演着this角色。 一些函数在结构中不需要任何东西,但为了统一起见,我还是要传递指针。 编译器是否会注意到该参数未被使用并且省略了为其分配寄存器?

为什么我必须在g ++中启用优化才能进行简单的数组访问?

我在C ++(gcc / Linux)中使用了一个double s的std::vector编写了一个简单的高斯消元法。 现在我已经看到运行时依赖于编译器的优化级别(使用-O3速度提高了5倍)。 我写了一个小测试程序并收到了类似的结果。 问题不在于矢量的分配,也没有任何resize等。 陈述这是一个简单的事实: 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*) […]

易失性和编译器优化

如果关闭编译器优化即(gcc -o0 ….),那么’volatile’关键字没有区别可以吗? 我已经制作了一些示例’C’程序,并且只有在打开编译器优化即((gcc -o1 ….)时才能看到生成的汇编代码中volatile和non-volatile之间的区别。

gcc复合常数折叠

似乎gcc对复杂的常量折叠有一些限制。 这是一个例子: static inline unsigned int DJBHash(const char *str) { int i; unsigned int hash = 5381; for(i = 0; i < strlen(str); i++) { hash = ((hash << 5) + hash) + str[i]; } return hash; } int f(void) { return DJBHash("01234567890123456"); } 当使用-O3优化级别(gcc 4.8)运行时,它很好地展开了DJBHash中的循环,并在编译期间计算该字符串的哈希值。 但是,当字符串长一个字符时, return DJBHash(“012345678901234567”); 它不再折叠它并使用条件跳转指令生成循环。 我想将任意长度的文字字符串折叠为其哈希值作为编译时常量。 这可以吗? 澄清 我的问题是关于gcc的常量折叠优化(参见标题 – […]

为什么gcc autovectorization对3×3的卷积矩阵不起作用?

我已经为卷积矩阵实现了以下程序 #include #include #define NUM_LOOP 1000 #define N 128 //input or output dimention 1 #define MN //input or output dimention 2 #define P 5 //convolution matrix dimention 1 if you want a 3×3 convolution matrix it must be 3 #define QP //convolution matrix dimention 2 #define Csize P*Q #define Cdiv 1 //div for filter #define […]

是GCC的选择-O2打破这个小程序还是我有未定义的行为

我在一个非常大的应用程序中发现了这个问题,从中做了一个SSCCE。 我不知道代码是否有未定义的行为或-O2打破它。 用gcc ac -o a.exe -O2 -Wall -Wextra -Werror编译它时会输出5 。 但是在没有-O2 (例如-O1 )的情况下编译时会打印25 ,或者在2个注释行中取消注释(防止内联)。 #include #include // __attribute__((noinline)) int f(int* todos, int input) { int* cur = todos-1; // fixes the ++ at the beginning of the loop int result = input; while(1) { cur++; int ch = *cur; // printf(“(%i)\n”, ch); switch(ch) { […]

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

处理器中的分区需要很长时间,所以我想问如何以最快的方式检查数字是否可以被其他数字整除,在我的情况下我需要检查数字是否可以被15整除。 此外,我一直在浏览网页,并找到有趣的方法来检查数字是否可以被某些数字整除,但我正在寻找快速选项。 注意:由于分工需要很长时间,我正在寻找没有/和%答案。

for循环被忽略(优化?)out

我正在使用for / while循环来实现代码中的延迟。 延迟的持续时间在这里并不重要,尽管它足够大而值得注意。 这是代码片段。 uint32_t i; // Do something useful for (i = 0; i < 50000000U; ++i) {} // Do something useful 我观察的问题是这个for循环不会被执行。 它可能会被编译器忽略/优化。 但是,如果我通过volatile限定循环计数器i ,则for循环似乎执行,我确实注意到执行中所需的延迟。 对于我使用/不使用volatile关键字的编译器优化的理解,这种行为似乎有点违反直觉。 即使循环计数器得到优化并存储在处理器寄存器中,计数器是否仍然可以工作,也许延迟较小? (因为内存提取开销被废除了。) 我正在构建的平台是Xtensa处理器(由Tensilica提供),C编译器是由Tensilica提供的,Xtensa C / C ++编译器以最高级别的优化运行。 我尝试了与gcc 4.4.7相同的-o3和ofast优化级别。 在这种情况下,延迟似乎有效。