相关疑难解决方法(0)

用于测试Collat​​z猜想的C++代码比手写程序集更快 - 为什么?

我为Project Euler Q14编写了这两个解决方案,在汇编和C++中.它们是用于测试Collat​​z猜想的相同蛮力方法.装配解决方案与组装

nasm -felf64 p14.asm && gcc p14.o -o p14
Run Code Online (Sandbox Code Playgroud)

C++是用.编译的

g++ p14.cpp -o p14
Run Code Online (Sandbox Code Playgroud)

部件, p14.asm

section .data
    fmt db "%d", 10, 0

global main
extern printf

section .text

main:
    mov rcx, 1000000
    xor rdi, rdi        ; max i
    xor rsi, rsi        ; i

l1:
    dec rcx
    xor r10, r10        ; count
    mov rax, rcx

l2:
    test rax, 1
    jpe even

    mov rbx, 3
    mul rbx
    inc rax
    jmp c1

even:
    mov rbx, 2 …
Run Code Online (Sandbox Code Playgroud)

c++ optimization performance x86 assembly

803
推荐指数
8
解决办法
14万
查看次数

哪个更快:while(1)或while(2)?

这是一位高级经理提出的面试问题.

哪个更快?

while(1) {
    // Some code
}
Run Code Online (Sandbox Code Playgroud)

要么

while(2) {
    //Some code
}
Run Code Online (Sandbox Code Playgroud)

我说两者都有相同的执行速度,因为里面的表达式while应该最终评估为truefalse.在这种情况下,两者都评估,true并且条件内没有额外的条件指令while.因此,两者都具有相同的执行速度,而我更喜欢(1).

但采访者自信地说:"检查你的基础知识.while(1)比快while(2)." (他没有测试我的信心)

这是真的?

另请参阅:"for(;;)"是否比"while(TRUE)"快?如果没有,为什么人们会使用它?

c performance while-loop

582
推荐指数
15
解决办法
9万
查看次数

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

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

C和汇编程序实际编译的是什么?

所以我发现C(++)程序实际上并没有编译成简单的"二进制"(我可能在这里遇到了一些问题,在这种情况下我很抱歉:D)但是对于一系列事物(符号表) ,os相关的东西,...)但......

  • 汇编程序"编译"到纯二进制文件?这意味着除了预定义的字符串等资源之外没有额外的东

  • 如果C编译成除了普通二进制文件以外的其他内容,那么小型汇编程序引导程序如何只是将指令从HDD复制到内存并执行它们?我的意思是,如果操作系统内核(可能用C语言编写)编译成不同于普通二进制文件的东西 - 引导加载程序如何处理它?

编辑:我知道汇编程序没有"编译",因为它只有你的机器的指令集 - 我没有找到汇编程序"汇编"的好词.如果你有一个,请留在这里作为评论,我会改变它.

c c++ compiler-construction assembly linker

47
推荐指数
4
解决办法
2万
查看次数

编译器对编译时分支做了什么?

编辑:我把"if/else"案例作为一个例子,有时可以在编译时解决(例如,当涉及静态值时,cf <type_traits>).将以下答案调整为其他类型的静态分支(例如,多个分支或多标准分支)应该是直截了当的.请注意,使用模板元编程的编译时分支不是此处的主题.


在像这样的典型代码中

#include <type_traits>

template <class T>
T numeric_procedure( const T& x )
{
    if ( std::is_integral<T>::value )
    {
        // Integral types
    }
    else
    {
        // Floating point numeric types
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在代码中稍后定义特定模板类型时,编译器会优化if/else语句吗?

一个简单的替代方案是写这样的东西:

#include <type_traits>

template <class T>
inline T numeric_procedure( const T& x )
{
    return numeric_procedure_impl( x, std::is_integral<T>() );
}

// ------------------------------------------------------------------------

template <class T>
T numeric_procedure_impl( const T& x, std::true_type const )
{
    // Integral types
}

template <class T>
T numeric_procedure_impl( const …
Run Code Online (Sandbox Code Playgroud)

c++ templates if-statement type-traits c++11

33
推荐指数
3
解决办法
4051
查看次数

如何编译C程序而不进行任何优化

如何在不使用gcc/g ++进行任何优化的情况下编译C程序?

c gcc

15
推荐指数
3
解决办法
1万
查看次数

C循环优化有助于最终分配

因此,对于我在计算机系统课程中的最终作业,我们需要优化这些forloops,使其比原始版本更快.使用我们的linux服务器,基本等级不到7秒,完整等级不到5秒.我在这里的代码大约需要5.6秒.我想我可能需要以某种方式使用指针来使它更快,但我不是很确定.任何人都可以提供我的任何提示或选项吗?非常感谢!

QUICKEDIT:文件必须保持50行或更少,我忽略了教师所包含的那些注释行.

#include <stdio.h>
#include <stdlib.h>

// You are only allowed to make changes to this code as specified by the comments in it.

// The code you submit must have these two values.
#define N_TIMES     600000
#define ARRAY_SIZE   10000

int main(void)
{
    double  *array = calloc(ARRAY_SIZE, sizeof(double));
    double  sum = 0;
    int     i;

    // You can add variables between this comment ...
    register double sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0, …
Run Code Online (Sandbox Code Playgroud)

c optimization loops compiler-optimization debug-mode

8
推荐指数
2
解决办法
5650
查看次数

为什么整数除以-1(负一)导致FPE?

我的任务是表达一些看似奇怪的C代码行为(在x86上运行).我可以很容易地完成其他所有事情,但这个让我很困惑.

代码段1输出 -2147483648

int a = 0x80000000;
int b = a / -1;
printf("%d\n", b);
Run Code Online (Sandbox Code Playgroud)

代码片段2没有输出任何内容,并给出了一个 Floating point exception

int a = 0x80000000;
int b = -1;
int c = a / b;
printf("%d\n", c);
Run Code Online (Sandbox Code Playgroud)

我很清楚Code Snippet 1(1 + ~INT_MIN == INT_MIN)的结果的原因,但是我不太明白整数除以-1如何生成FPE,也不能在我的Android手机(AArch64,GCC 7.2.0)上重现它.代码2只输出与代码1相同,没有任何例外.它是x86处理器的隐藏bug功能吗?

该任务没有告诉任何其他内容(包括CPU架构),但由于整个课程基于桌面Linux发行版,您可以放心地认为它是一个现代的x86.


编辑:我联系了我的朋友,他在Ubuntu 16.04(Intel Kaby Lake,GCC 6.3.0)上测试了代码.结果与所指定的任何内容一致(代码1输出所述内容,代码2与FPE崩溃).

c x86 gcc x86-64 floating-point-exceptions

8
推荐指数
2
解决办法
1188
查看次数

GCC标准优化行为

在这里,我使用-O2优化级别(使用gcc 4.8.4)编译输入程序并测量执行时间:

gcc -O2 -c test.c -o obj.o
TIMEFORMAT='%3R' &&  time(./obj.o)
execution time = 1.825
Run Code Online (Sandbox Code Playgroud)

当我将-O2标志替换为在-O2 https://gcc.gnu.org/onlinedocs/gcc-4.8.4/gcc/Optimize-Options级别中GCC manuel中定义的选项列表. html#Optimize-Options就像这样:

gcc -fauto-inc-dec -fcompare-elim -fcprop-registers -fdce -fdefer-pop -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion -fipa-pure-const -fipa-profile -fipa-reference -fmerge-constants -fsplit-wide-types -ftree-bit-ccp  -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-phiprop -ftree-slsr -ftree-sra -ftree-pta -ftree-ter -funit-at-a-time -fthread-jumps -falign-functions  -falign-jumps -falign-loops  -falign-labels -fcaller-saves -fcrossjumping -fcse-follow-jumps  -fcse-skip-blocks -fdelete-null-pointer-checks -fdevirtualize -fexpensive-optimizations -fgcse  -fgcse-lm  -fhoist-adjacent-loads -finline-small-functions -findirect-inlining -fipa-sra -foptimize-sibling-calls -fpartial-inlining -fpeephole2 -fregmove  -freorder-blocks  -freorder-functions -frerun-cse-after-loop -fsched-interblock  -fsched-spec …
Run Code Online (Sandbox Code Playgroud)

c performance gcc execution-time compiler-optimization

7
推荐指数
1
解决办法
210
查看次数

使用 strlen 与停止为零的字符串操作的性能

当我用 C++ 为字符串编写一个类时,我发现了一个关于执行速度的奇怪行为。我将以upper方法的以下两个实现为例:

class String {

    char* str;

    ...

    forceinline void upperStrlen();
    forceinline void upperPtr();
};

void String::upperStrlen()
{
    INDEX length = strlen(str);

    for (INDEX i = 0; i < length; i++) {
        str[i] = toupper(str[i]);
    }
}

void String::upperPtr()
{
    char* ptr_char = str;

    for (; *ptr_char != '\0'; ptr_char++) {
        *ptr_char = toupper(*ptr_char);
    }
}
Run Code Online (Sandbox Code Playgroud)

INDEX 是 uint_fast32_t 的简单类型定义。

现在我可以在 main.cpp 中测试这些方法的速度:

#define TEST_RECURSIVE(_function)                    \
{                                                    \
    bool ok = true;                                  \
    clock_t before = clock();                        \
    for …
Run Code Online (Sandbox Code Playgroud)

c++ string performance gcc x86-64

6
推荐指数
1
解决办法
190
查看次数