Sind 64-Bit-Programme größer und schneller als 32-Bit-Versionen?

83

Ich denke, ich konzentriere mich auf x86, aber ich bin allgemein an der Umstellung von 32 auf 64 Bit interessiert.

Logischerweise kann ich sehen, dass Konstanten und Zeiger in einigen Fällen größer sind, sodass Programme wahrscheinlich größer sind. Und der Wunsch, aus Effizienzgründen Speicher an Wortgrenzen zuzuweisen, würde mehr Leerraum zwischen den Zuweisungen bedeuten.

Ich habe auch gehört, dass der 32-Bit-Modus auf dem x86 seinen Cache beim Kontextwechsel aufgrund möglicher überlappender 4G-Adressräume leeren muss.

Was sind die wirklichen Vorteile von 64-Bit?

Und als ergänzende Frage, wäre 128 Bit noch besser?

Bearbeiten:

Ich habe gerade mein erstes 32/64-Bit-Programm geschrieben. Es erstellt verknüpfte Listen / Bäume aus 16-Byte- (32b-Version) oder 32-Byte- (64b-Version) Objekten und druckt viel auf stderr - kein wirklich nützliches Programm und nichts Typisches, aber es ist mein erstes.

Größe: 81128 (32b) v 83672 (64b) - also kein großer Unterschied

Geschwindigkeit: 17s (32b) v 24s (64b) - läuft unter 32-Bit-Betriebssystem (OS-X 10.5.8)

Aktualisieren:

Ich stelle fest, dass ein neues hybrides x32-ABI (Application Binary Interface) entwickelt wird, das 64b ist, aber 32b-Zeiger verwendet. Bei einigen Tests führt dies zu kleinerem Code und einer schnelleren Ausführung als 32b oder 64b.

https://sites.google.com/site/x32abi/

Philcolbourn
quelle
1
Scheint wie ein Duplikat von stackoverflow.com/questions/324015/…
Suma
1
Und meine von vor ein paar Tagen: stackoverflow.com/questions/2334148/…
Mr. Boy
Ich stimme zu, dass es einige Überlappungen gibt, aber noch keine Abnehmer im CPU-Cache und in 128-Bit-Teilen. Danke Suma und John für die Links.
Philcolbourn
Werfen
Sean
"Ich habe auch gehört, dass der 32-Bit-Modus auf dem x86 seinen Cache beim Kontextwechsel aufgrund möglicher überlappender 4G-Adressräume leeren muss." Können Sie mich bitte auf eine Referenz verweisen, die darüber spricht?
gkb0986

Antworten:

29

Sofern Sie nicht auf mehr Speicher zugreifen müssen, als Ihnen die 32b-Adressierung ermöglicht, sind die Vorteile, falls vorhanden, gering.

Wenn Sie auf einer 64b-CPU arbeiten, erhalten Sie dieselbe Speicherschnittstelle, unabhängig davon, ob Sie 32b- oder 64b-Code ausführen (Sie verwenden denselben Cache und denselben BUS).

Während die x64-Architektur einige weitere Register aufweist, die einfachere Optimierungen ermöglichen, wird dem häufig dadurch entgegengewirkt, dass Zeiger jetzt größer sind und die Verwendung von Strukturen mit Zeigern zu einem höheren Speicherverkehr führt. Ich würde den Anstieg der Gesamtspeicherauslastung für eine 64b-Anwendung im Vergleich zu einer 32b-Anwendung auf etwa 15 bis 30% schätzen.

Suma
quelle
2
Wie beurteilen Sie den vorgeschlagenen x32-ABI?
Philcolbourn
Ich denke, memcpy und strcpy werden schneller als 32-Bit-CPU sein, weil es jedes Mal ein Wort liest, da ein Wort 8 Bytes auf 64-Bit-CPU ist
Mark Ma
43

Ich sehe normalerweise eine 30% ige Geschwindigkeitsverbesserung für rechenintensiven Code auf x86-64 im Vergleich zu x86. Dies ist höchstwahrscheinlich auf die Tatsache zurückzuführen, dass wir 16 x 64-Bit-Allzweckregister und 16 x SSE-Register anstelle von 8 x 32-Bit-Allzweckregistern und 8 x SSE-Registern haben. Dies ist mit dem Intel ICC-Compiler (11.1) unter einem x86-64-Linux möglich - die Ergebnisse mit anderen Compilern (z. B. gcc) oder mit anderen Betriebssystemen (z. B. Windows) können natürlich abweichen.

Paul R.
quelle
1
Mit "rechenintensiv" meinen Sie Grafiken, Matrix, DFTs?
Philcolbourn
4
@phil: Ja, hauptsächlich Bildverarbeitung, meistens Ganzzahl (Fixpunkt), viel SIMD-Code usw.
Paul R
Ich habe beobachtet, dass 64-Bit-Compiler die SSE-Register verwenden, während 32-Bit-Compiler die Standard-ALU verwenden. Dies beschleunigt den 64-Bit-Code aufgrund der schmaleren FP-Breite (64 gegenüber 80) und zusätzlicher Anweisungen.
IamIC
16

Unabhängig von den Vorteilen würde ich vorschlagen, dass Sie Ihr Programm immer für die Standardwortgröße des Systems (32-Bit oder 64-Bit) kompilieren, da Sie eine Bibliothek als 32-Bit-Binärdatei kompilieren und auf einer 64-Bit-Binärdatei bereitstellen System werden Sie jeden, der eine Verknüpfung mit Ihrer Bibliothek herstellen möchte, dazu zwingen, seine Bibliothek (und alle anderen Bibliotheksabhängigkeiten) als 32-Bit-Binärdatei bereitzustellen, wenn die 64-Bit-Version die Standardeinstellung ist. Dies kann für alle ein ziemliches Ärgernis sein. Geben Sie im Zweifelsfall beide Versionen Ihrer Bibliothek an.

In Bezug auf die praktischen Vorteile von 64-Bit ... ist das offensichtlichste, dass Sie einen größeren Adressraum erhalten. Wenn Sie also eine Datei mit mmap versehen, können Sie mehr davon gleichzeitig adressieren (und größere Dateien in den Speicher laden). Ein weiterer Vorteil besteht darin, dass viele Ihrer arithmetischen Operationen parallelisiert werden können (z. B. zwei Paare von 32-Bit-Zahlen in zwei Registern platzieren und zwei Additionen in einer einzelnen Additionsoperation ausführen), vorausgesetzt, der Compiler leistet gute Arbeit bei der Optimierung Zahlenberechnungen werden schneller ausgeführt. Das heißt, das ganze 64-Bit- und 32-Bit-Ding hilft Ihnen bei asymptotischer Komplexität überhaupt nicht. Wenn Sie also Ihren Code optimieren möchten, sollten Sie sich wahrscheinlich eher die Algorithmen als die konstanten Faktoren wie diese ansehen.

EDIT :
Bitte ignorieren Sie meine Aussage über die parallelisierte Addition. Dies wird nicht durch eine gewöhnliche add-Anweisung ausgeführt ... Ich habe das mit einigen der vektorisierten / SSE-Anweisungen verwechselt. Ein genauerer Vorteil, abgesehen vom größeren Adressraum, besteht darin, dass es allgemeinere Register gibt, was bedeutet, dass mehr lokale Variablen in der CPU-Registerdatei verwaltet werden können, auf die viel schneller zugegriffen werden kann, als wenn Sie die Variablen in das Verzeichnis einfügen Programmstapel (was normalerweise bedeutet, in den L1-Cache zu gehen).

Michael Aaron Safyan
quelle
> "Zum Beispiel zwei Paare von 32-Bit-Zahlen in zwei Registern platzieren und zwei Adds in einer Single-Add-Operation ausführen" Gibt es da draußen einen Compiler, der dies tut? Dies scheint auch auf x86 mit SSE-Anweisungen möglich zu sein.
Suma
Wenn man über solche "zwei Adds in einem" mehr nachdenkt, ist das ein Unsinn und kein Compiler kann dies als Optimierung tun, da das Addieren von niedrigeren 32b in höhere 32b überlaufen könnte. Dazu benötigen Sie SIMD-Anweisungen.
Suma
Ich denke, wenn Sie daran interessiert wären, könnten Sie mehrere 16-Bit-Arithmetik in 64-Bit-Registern ausführen. Scheint chaotisch zu sein, aber ich wette, es wurde getan.
Philcolbourn
'Constant Factors' - klingt wie etwas, das Brian Harvey sagen würde.
Philcolbourn
5

64-Bit verfügt nicht nur über mehr Register, sondern auch standardmäßig über SSE2. Dies bedeutet, dass Sie tatsächlich einige Berechnungen parallel durchführen können. Die SSE-Erweiterungen hatten auch andere Extras. Aber ich denke, der Hauptvorteil besteht darin, nicht auf das Vorhandensein der Erweiterungen prüfen zu müssen. Wenn es x64 ist, ist SSE2 verfügbar. ... wenn mein Gedächtnis mir richtig dient.

Amokcrow
quelle
4

Ich programmiere eine Schach-Engine namens Foolsmate . Die beste Bewegungsextraktion mit einer Minimax-basierten Baumsuche bis zur Tiefe 9 (von einer bestimmten Position) ergab:

zur Win32Konfiguration: ~ 17.0s;

nach dem Wechsel zur x64Konfiguration: ~ 10.3s;

Das sind 41% der Beschleunigung!

blutig
quelle
2

Die einzige Rechtfertigung für das Verschieben Ihrer Anwendung auf 64-Bit ist, dass in Anwendungen wie großen Datenbanken oder ERP-Anwendungen mit mindestens 100 gleichzeitigen Benutzern mehr Speicher benötigt wird, wobei das Limit von 2 GB relativ schnell überschritten wird, wenn Anwendungen für eine bessere Leistung zwischengespeichert werden. Dies ist insbesondere unter Windows-Betriebssystemen der Fall, bei denen Integer und Long immer noch 32 Bit sind (sie haben die neue Variable _int64. Nur Zeiger sind 64 Bit. Tatsächlich ist WOW64 unter Windows x64 stark optimiert, sodass 32-Bit-Anwendungen unter 64-Bit-Windows mit geringer Strafe ausgeführt werden Betriebssystem. Meine Erfahrung unter Windows x64 ist, dass die 32-Bit-Anwendungsversion 10-15% schneller als die 64-Bit-Version ausgeführt wird, da Sie im vorherigen Fall zumindest für proprietäre Speicherdatenbanken Zeigerarithmen für die Verwaltung des B-Tree verwenden können (der prozessorintensivste Teil von Datenbanksystemen). . Rechenintensive Anwendungen, die große Dezimalstellen für höchste Genauigkeit erfordern, die das Double unter 32-64-Bit-Betriebssystem nicht bietet. Diese Anwendungen können _int64 nativ anstelle der Softwareemulation verwenden. Natürlich zeigen große festplattenbasierte Datenbanken auch eine Verbesserung gegenüber 32 Bit, einfach aufgrund der Möglichkeit, großen Speicher zum Zwischenspeichern von Abfrageplänen usw. zu verwenden.

GirishK
quelle
Erstens intbleibt überall 32-Bit, unabhängig von der Wortgröße der Ausführungsumgebung. Für welchen Compiler ist longbeim Kompilieren für 64-Bit noch 32-Bit? Behauptest du, dass MSVC dies tut? AFAIK, dies wird sogar [grob] im C ++ 11-Standard behandelt: sizeof(long) == sizeof(void*)Bitte, jemand, korrigieren Sie mich, wenn ich falsch liege, da ich keinen einfachen Zugang zu MSVC habe.
Matthew Hall
3
@Matthew Hall: Der Windows 64-Bit-Betriebssystemstandard und damit MSVC folgen diesem LLP64-Modell (gegenüber LP64 für Unix-Varianten). Siehe ( msdn.microsoft.com/en-us/library/3b2e7499(v=vs.100).aspx ).
GirishK
1

Bei jedem Speicherabruf werden mehr Daten zwischen CPU und RAM übertragen (64 Bit statt 32 Bit), sodass 64-Bit-Programme schneller ausgeführt werden können, sofern sie so geschrieben sind, dass sie dies ordnungsgemäß nutzen.

Rune Aamodt
quelle
10
Eigentlich ist das nicht so: Der Speicherbus hat eine beliebige Breite, was nichts Wesentliches mit der Breite der Prozessorregister zu tun hat. Einige 32-Bit-Systeme rufen jeweils 128 Bit ab, es gibt 64-Bit-Systeme, die jeweils 32 Bit abrufen, und sogar 32-Bit-Systeme, die nicht mehr als 8 Bit gleichzeitig abrufen.
Andrew McGregor
OK, das war mir nicht bewusst - ist es nicht richtig, dass ein einzelner mov-Befehl 64 Bit auf einer 64-Bit-CPU und 32 Bit auf einer 32-Bit-CPU überträgt? Wenn also eine große Speichermenge von Punkt A nach Punkt B kopiert wird, bedeutet dies zumindest, dass weniger Bewegungsbefehle auf einer 64-Bit-CPU ausgeführt werden müssen (selbst wenn der Speicherbus der Engpass ist)?
Rune Aamodt
2
Wenn Sie viel Speicher verschieben, verwenden Sie 128b SIMD-Anweisungen sowohl für x86 als auch für x64.
Suma
Was genau gibt es für "64-Bit-Systeme, die jeweils 32 abrufen"? Bitte nennen Sie einige. Wenn ja, sind es wirklich "64-Bit-Systeme"?
Johnny
1

Im speziellen Fall von x68 bis x68_64 ist das 64-Bit-Programm ungefähr gleich groß, wenn nicht etwas kleiner, verwendet etwas mehr Speicher und läuft schneller. Meistens liegt dies daran, dass x86_64 nicht nur 64-Bit-Register hat, sondern auch doppelt so viele. x86 verfügt nicht über genügend Register, um kompilierte Sprachen so effizient wie möglich zu gestalten. Daher verwendet x86-Code viele Anweisungen und Speicherbandbreiten, um Daten zwischen Registern und Speicher hin und her zu verschieben. x86_64 hat viel weniger davon, benötigt also etwas weniger Platz und läuft schneller. Gleitkomma- und Bit-Twiddling-Vektorbefehle sind in x86_64 ebenfalls viel effizienter.

Im Allgemeinen ist 64-Bit-Code jedoch nicht unbedingt schneller und in der Regel größer, sowohl für die Code- als auch für die Speichernutzung zur Laufzeit.

Andrew McGregor
quelle
2
Ich verstehe den Punkt, den Sie machen, nicht ganz. Anfangs (erster Satz) sagen Sie, dass 64-Bit-Programme im Allgemeinen schneller laufen, aber dann scheint Ihr letzter Satz all das zurückzudrehen, um "nicht wirklich" zu sagen
SN
1

Alle Anwendungen, die eine CPU-Auslastung erfordern, wie z. B. Transcodierung, Anzeigeleistung und Medienwiedergabe, ob Audio- oder Videodaten, erfordern (zu diesem Zeitpunkt) sicherlich die Verwendung von 64-Bit gegenüber 32-Bit, da die CPU in der Lage ist, mit dem Problem umzugehen Datenmenge, die darauf geworfen wird. Es geht weniger um den Adressraum als vielmehr um die Art und Weise, wie mit den Daten umgegangen wird. Ein 64-Bit-Prozessor mit 64-Bit-Code wird eine bessere Leistung erzielen, insbesondere bei mathematisch schwierigen Dingen wie Transcodierung und VoIP-Daten. Tatsächlich sollte jede Art von "mathematischen" Anwendungen von der Verwendung von 64-Bit-CPUs und Betriebssystemen profitieren. Beweise mir das Gegenteil.

Dave Vanian
quelle
Nein . Das wird es nicht. Wenn der RAM-Bedarf 4 GB überschreitet, ist nur dieser schneller. In einer 32-Bit-Architektur können Sie problemlos nach 1000 Millionen Ganzzahl-Arrays in weniger als 4 GB Daten suchen. Die Verwendung einer 64-Bit-Maschine hier wird also langsamer
sapy