Frage

Die kompiliert werden, um schnelleren code:"ans = n * 3" oder "ans = n+(n*2)"?

Unter der Annahme, dass n ist entweder ein int oder ein long, und es ist auf einem modernen Win32 Intel box.

Wäre dies anders, wenn es einige dereferenzieren, das ist, was dieser wäre schneller?

long    a;
long    *pn;
long     ans;

...
*pn = some_number;
ans = *pn * 3;

Oder

ans = *pn+(*pn*2);

Oder ist es etwas, das man brauchen sich keine sorgen darüber, wie die Optimierung von Compilern sind wahrscheinlich, um für dieses Konto in jedem Fall?

War es hilfreich?

Lösung

IMO solche Mikro-Optimierung ist nicht notwendig, es sei denn, Sie mit einem exotischen Compiler arbeiten. Ich würde die Lesbarkeit auf dem ersten Platz.

Andere Tipps

Es spielt keine Rolle. Moderne Prozessoren können eine ganze Zahl MUL-Befehl in einem Taktzyklus oder weniger ist, im Gegensatz zu älteren Verarbeitern ausführen, die eine Reihe von Verschiebungen durchzuführen benötigt und fügt intern um die MUL, wodurch die Verwendung mehrerer Zyklen durchzuführen. Ich würde darauf wetten, dass

MUL EAX,3

führt schneller als

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

Der letzte Prozessor, wo diese Art von Optimierung nützlich gewesen wäre, war wahrscheinlich das 486. (ja, das ist voreingenommen zu Intel-Prozessoren, aber ist wahrscheinlich repräsentativ für andere Architekturen als auch).

In jedem Fall sollte jeder vernünftiger Compiler in der Lage sein, den kleinsten / schnellsten Code zu generieren. Also immer mit Lesbarkeit geht zuerst.

Wie es ist einfach, es zu messen Sie sich, warum das nicht tun? (Mit gcc und time von Cygwin)

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

Machen Sie den Test für ein paar Mal, und wiederholen Sie für den anderen Fall.

Wenn Sie auf dem Assembler-Code spähen, gcc -S -O2 test1.c

Dies würde, hängt von dem Compiler, deren Konfiguration und dem umgebenden Code.

Sie sollten nicht versuchen und erraten, ob die Dinge sind ‚schneller‘ ohne Messungen.

Allgemein sollten Sie nicht über diese Art von Sachen nanoskaligen Optimierung heutzutage Sorge - es ist fast immer eine vollständige Irrelevanz ist, und wenn man wirklich in einer Domäne arbeitet, wo es darauf ankam, würden Sie bereits verwenden ein Profiler und an der Assemblersprache Ausgabe des Compilers an.

Es ist nicht schwer, herauszufinden, was der Compiler mit Ihrem Code tut (ich benutze DevStudio 2005 hier). Schreiben Sie ein einfaches Programm mit dem folgenden Code:

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

Legen Sie einen Haltepunkt auf der Mittellinie und den Code auszuführen, den Debugger verwenden. Wenn der Breakpoint ausgelöst wird, klicken Sie rechts auf der Quelldatei und wählen Sie „Zur Demontage Go“. Sie werden nun ein Fenster mit dem Code haben die CPU ausgeführt wird. Sie werden in diesem Fall feststellen, dass die letzten beiden Zeilen produzieren genau die gleichen Anweisungen, nämlich „lea eax, [ebx + EBX * 2]“ (nicht Bitverschiebung und das Hinzufügen in diesem speziellen Fall). Auf einem modernen IA32-CPU, ist es wahrscheinlich effizientes, ein gerade MUL anstatt Bitverschieben aufgrund pipelineing Natur der CPU zu tun, die eine Strafe entstehen, wenn zu früh einen modifizierten Wert verwendet wird.

Dies zeigt, was aku spricht, nämlich Compiler sind klug genug, um die besten Anweisungen für Ihren Code zu wählen.

Es ist, hängt von der Compiler Sie tatsächlich verwenden, aber sehr wahrscheinlich auf den gleichen Code, den sie übersetzen.

Sie können es selbst überprüfen, indem ein kleines Testprogramm zu schaffen und seine Demontage zu überprüfen.

Die meisten Compiler sind intelligent genug, um eine ganze Zahl Multiplikation in eine Reihe von Bit-Verschiebungen zu zersetzen und fügt hinzu. Ich weiß nicht, über Windows-Compiler, aber zumindest mit gcc Sie können es den Assembler ausspucken zu bekommen, und wenn Sie das betrachten können Sie wahrscheinlich identisch Assembler für beide Arten des Schreibens es sehen.

Es kümmert sich nicht darum. Ich denke, dass es wichtigere Dinge zu optimieren. Wie viel Zeit haben Sie investiert denken und diese Frage schriftlich statt Codierung und Testen von sich selbst?

: -)

Solange man einen anständigen optimierenden Compiler verwenden, nur Code schreiben, die einfach für die Compiler zu verstehen . Dies macht es einfacher für die Compiler clevere Optimierungen durchzuführen.

Sie diese Frage an, dass eine Optimierung der Compiler mehr über die Optimierung kennt als Sie. So vertrauen den Compiler. Verwenden Sie n * 3.

Hier finden Sie aktuelle als auch.

Compiler sind gut im Code wie bei Ihnen zu optimieren. Jeder moderne Compiler würde den gleichen Code für beide Fälle produzieren und zusätzlich ersetzen * 2 durch eine Verschiebung nach links.

Vertrauen Sie Ihren Compiler kleine Stücke von Code, so zu optimieren. Ablesbarkeit ist viel wichtiger, auf Codeebene. Echte Optimierung auf einer höheren Ebene kommen sollte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top