Warum ist dieser C ++ - Code schneller als meine handgeschriebene Assembly zum Testen der Collatz-Vermutung?

Ich schrieb diese zwei Lösungen für Projekt Euler F14, in Assembler und in C++. Sie sind die gleichen brute-force-Ansatz für die Prüfung der Collatz-Vermutung. Die Montage-Lösung wurde montiert mit

nasm -felf64 p14.asm && gcc p14.o -o p14

C++ kompiliert wurde mit

g++ p14.cpp -o p14

Montage 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
    xor rdx, rdx
    div rbx

c1:
    inc r10
    cmp rax, 1
    jne l2

    cmp rdi, r10
    cmovl rdi, r10
    cmovl rsi, rcx

    cmp rcx, 2
    jne l1

    mov rdi, fmt
    xor rax, rax
    call printf
    ret

C++, p14.cpp

#include <iostream>

using namespace std;

int sequence(long n) {
    int count = 1;
    while (n != 1) {
        if (n % 2 == 0)
            n /= 2;
        else
            n = n*3 + 1;

        ++count;
    }

    return count;
}

int main() {
    int max = 0, maxi;
    for (int i = 999999; i > 0; --i) {
        int s = sequence(i);
        if (s > max) {
            max = s;
            maxi = i;
        }
    }

    cout << maxi << endl;
}

Weiß ich über die compiler-Optimierungen zur Verbesserung der Geschwindigkeit und alles, aber ich sehe nicht viele Möglichkeiten zur Optimierung meiner Montage-Lösung weiter (sprechen programmatisch nicht mathematisch).

Den C++ - code Modul-jeder Begriff und jeder division auch Begriff, wo die Montage ist nur eine division pro sogar Begriff.

Aber die assembly ist, die durchschnittlich 1 Sekunde länger als die C++ - Lösung. Warum ist das so? Ich Frage aus vor allem Neugier.

Ausführungszeiten

Mein system: 64-bit-Linux auf 1.4 GHz Intel Celeron 2955U (Haswell-Mikroarchitektur).

Kommentar zu dem Problem - Öffnen
Haben Sie untersucht die assembly-code, der GCC erzeugt für Ihr C++ - Programm? Kommentarautor: ruakh
Kompilieren mit -S, um die assembly, die der compiler generiert. Der compiler ist schlau genug zu erkennen, dass der E-Modul hat die division an der gleichen Zeit. Kommentarautor: user3386109
Ich denke deine Optionen sind 1. Ihre Messtechnik ist fehlerhaft, 2. Der compiler schreibt besser-assembly, die Sie, oder 3. Der compiler verwendet Magie. Kommentarautor: Galik
@jefferson kann Der compiler schneller brute-force. Zum Beispiel, vielleicht mit der SSE-Anweisungen. Kommentarautor: immibis

InformationsquelleAutor der Frage jeffer son | 2016-11-01

Schreibe einen Kommentar