64-Bit-Integers auf 32-Bit-Windows
-
Für ein performancekritisches Programm brauche ich Bitoperatoren für 64-Bit-Integers. Aktuelle Hardware sollte diese ja direkt unterstützen.
Aber brauche ich dafür auch ein 64-Bit-Betriebssystem, um diese nutzen zu können?Ich verwende Win32 und Visual C++ 2010. Dort gibt es ja den __int64 Datentyp.
Ist dieser ein richtiger 64-Bit Datentyp, der von der Hardware unterstützte 64-Bit-Operationen durchführt oder besteht der nur aus 2 32-Bit-Zahlen?
-
Nimm halt (unsigned) long long.
-
Senfti schrieb:
Ich verwende Win32 und Visual C++ 2010. Dort gibt es ja den __int64 Datentyp.
Ist dieser ein richtiger 64-Bit Datentyp, der von der Hardware unterstützte 64-Bit-Operationen durchführt oder besteht der nur aus 2 32-Bit-Zahlen?Wenn du für 64bit kompilierst ist es natürlich ein 64bit Integer. Unter 32bit besteht er aus 2 32bit-Wörtern.
-
314159265358979 schrieb:
Nimm halt (unsigned) long long.
Unterstützt VC10 das eig.?
-
Das fragst du gerade mich, den MSVC+Windows Hasser schlechthin? Ja, seit Ewigkeiten schon...
-
Nur so fürs Protokoll:
long longist kein 64-bit Integer in C++.std::int64_tist einer. Deswegen hat der nämlich die 64 im Namen.
-
TyRoXx schrieb:
Nur so fürs Protokoll:
long longist kein 64-bit Integer in C++.Er ist nur garantiert mindestens 64 Bit breit.

-
TyRoXx schrieb:
Deswegen hat der nämlich die 64 im Namen.
Hätt' ich nie gedacht.

Edit: Ist
int64_tnicht eh ein typedef auflong long?
-
Hacker schrieb:
Edit: Ist
int64_tnicht eh ein typedef auflong long?Der Standard sagt dazu ganz klar: Möglicherweise. :p
-
Es ist ein Unterschied, ob du int64_t oder __int64 verwendest. Denn __int64 ist ein Compiler-Builtin von MSVC, genauso wie zb float oder int. int64_t dagegen ist ein typedef.
-
Heißt das jetzt, ich kann 64-bit Integers verwenden, allerdings werden diese bei 32-bit Betriebssystemen vom Prozessor als 2 32-bit Integers behandelt?
Somit werden 64-bit Integers auf 64-bit Betriebssytemen schneller verarbeitet als auf 32-bit Betriebssystemen, egal ob die Hardware 64-bit unterstützt?Falls ich das falsch interpretiert habe, erübrigt sich die Frage, ob man auf 64-bit Hardware mit 32-bit Betriebssystem nicht doch irgendwie direkt mit 64-bit Integers arbeiten kann (mit irgendwelchen Extensions, wie bei OpenGL Hardwarefeatures genutzt werden können).
Noch eine Frage: Können übliche Prozessoren mehr Funktionen, als in C++ vorhanden sind? Wenn ja, wie kann ich diese verwenden (z.B. würde ich mir eine hardwareunterstützte Suche nach dem niederwertigsten Bit, das 1 ist, wünschen)?
-
Senfti schrieb:
Heißt das jetzt, ich kann 64-bit Integers verwenden, allerdings werden diese bei 32-bit Betriebssystemen vom Prozessor als 2 32-bit Integers behandelt?
Somit werden 64-bit Integers auf 64-bit Betriebssytemen schneller verarbeitet als auf 32-bit Betriebssystemen, egal ob die Hardware 64-bit unterstützt?Ja, natürlich, wie sollte das sonst gehen? Wenn das Programm so geschrieben ist, dass es seine 64-Bit Zahlen in 2-32-Bit Rechenschritten verarbeitet, dann ist es egal, was die Hardware könnte. Das Programm sagt der Hardware, was wie getan wird, nicht umgekehrt. Und wenn das Programm davon ausgeht, dass die Hardware nur 32 Bit gleichzeitig kann, dann werden eben nur 32 Bit gleichzeitig benutzt.
Falls ich das falsch interpretiert habe, erübrigt sich die Frage, ob man auf 64-bit Hardware mit 32-bit Betriebssystem nicht doch irgendwie direkt mit 64-bit Integers arbeiten kann (mit irgendwelchen Extensions, wie bei OpenGL Hardwarefeatures genutzt werden können).
Nein, kann man nicht.
Noch eine Frage: Können übliche Prozessoren mehr Funktionen, als in C++ vorhanden sind? Wenn ja, wie kann ich diese verwenden (z.B. würde ich mir eine hardwareunterstützte Suche nach dem niederwertigsten Bit, das 1 ist, wünschen)?
C++ kennt gar keine Prozessorfunktionen. Die kennt der Compiler. Und der kennt in der Regel alle, die du ihn kennen lässt. Wenn du ein Programm so compilierst, dass es auch auf einem 386er laufen könnte (was bei 32-Bit Programmen die Regel ist), dann wird eben nur Code erzeugt, der die Funktionen eines 386ers nutzt. Wenn du sagst, dass er auch SSE4.2-Funktionen benutzen darf, dann wird ein Compiler, der aktuell genug ist diese zu kennen, sie auch nutzen, wo es etwas bringt*. Dann läuft das Programm eben nur auf den allerneuesten Intelprozessoren.
Falls du meinst, es besser zu können als dein Compiler (was durchaus sein kann, falls man als Programmierer den vollen Durchblick hat) oder falls dein Compiler zu alt ist, dann gibt es auch die Möglichkeit, selber in Assembler Code vorzugeben oder besser: Spezielle Bibliotheken zu nutzen, die diese CPU-Features gezielt anbieten (zu erhalten bei den Prozessorherstellern, z.B. die Intels Math Kernel Library). Die sind in der Regel nichts für Anfänger (siehe obiger Kommentar über den Durchblick).
Erwarte auch nicht zu viel von solchen Funktionen. Die Anwendungsszenarien sind recht speziell, es bringt sehr viel wenn man sehr oft die gleichen einfachen Operationen unabhängig auf eine riesige Menge gleichartiger Daten anwendet. Die meisten Programme tun dies nicht! Dann wird das Programm sogar langsamer, wenn man sich in den Kopf gesetzt hat, unbedingt diese Features nutzen zu wollen.
*: Genauer: Wo der Compiler denkst, dass es was bringt. Siehe auch die Erklärungen in den letzten beiden Absätzen über den Durchblick und darüber, was passiert, wenn man keinen Durchblick hat. Ich habe schon oft erlebt, dass der Compiler langsameren Code baut, wenn man ihm SSE&Co. erlaubt.
-
SeppJ schrieb:
Senfti schrieb:
Heißt das jetzt, ich kann 64-bit Integers verwenden, allerdings werden diese bei 32-bit Betriebssystemen vom Prozessor als 2 32-bit Integers behandelt?
Somit werden 64-bit Integers auf 64-bit Betriebssytemen schneller verarbeitet als auf 32-bit Betriebssystemen, egal ob die Hardware 64-bit unterstützt?Ja, natürlich, wie sollte das sonst gehen? Wenn das Programm so geschrieben ist, dass es seine 64-Bit Zahlen in 2-32-Bit Rechenschritten verarbeitet, dann ist es egal, was die Hardware könnte. Das Programm sagt der Hardware, was wie getan wird, nicht umgekehrt. Und wenn das Programm davon ausgeht, dass die Hardware nur 32 Bit gleichzeitig kann, dann werden eben nur 32 Bit gleichzeitig benutzt.
Man könnte vermutlich SSE oder SSE2 oder sowas verwenden - da gibt's ja ausreichend grosse Register.
Tun die Compiler aber glaube ich nicht, nichtmal wenn man SSE/SSE2 Support explizit aufdreht.
-
hustbaer schrieb:
Man könnte vermutlich SSE oder SSE2 oder sowas verwenden - da gibt's ja ausreichend grosse Register.
Tun die Compiler aber glaube ich nicht, nichtmal wenn man SSE/SSE2 Support explizit aufdreht.SSE1, was es auch in reinen 32-Bit Prozessoren gibt, kann nur mit 32-Bit Zahlen rechnen. Kann man von 32-Bit Code aus SSE2 und höher benutzen?
-
SeppJ schrieb:
hustbaer schrieb:
Man könnte vermutlich SSE oder SSE2 oder sowas verwenden - da gibt's ja ausreichend grosse Register.
Tun die Compiler aber glaube ich nicht, nichtmal wenn man SSE/SSE2 Support explizit aufdreht.SSE1, was es auch in reinen 32-Bit Prozessoren gibt, kann nur mit 32-Bit Zahlen rechnen. Kann man von 32-Bit Code aus SSE2 und höher benutzen?
Nein, laut
http://en.wikipedia.org/wiki/SSE2 schrieb:
AMD's implementation of SSE2 on the AMD64 (x86-64) platform includes an additional eight registers, doubling the total number to 16 (XMM0 through XMM15). These additional registers are only visible when running in 64-bit mode.
-
Die zusätzlichen acht Register sind im 32-Bit-Modus nicht nutzbar. Die acht ursprünglichen m.W. durchaus.
-
Caligulaminus schrieb:
Die zusätzlichen acht Register sind im 32-Bit-Modus nicht nutzbar. Die acht ursprünglichen m.W. durchaus.
Heute ist nicht mein Tag, geh auf Tauchstation *blubblub*
-
@SeppJ:
Naja... nachdem der 32 Bit Compiler vom MSVC nen /arch:SSE2 Switch hat, gehe ich mal davon aus dass es auch auf 32 Bit CPUs funktioniert.Und 64 Bit Integer Befehle gibt's bei SSE2 laut MSDN wohl auch.
Müsste man fast doch mal ausprobieren was MSVC mit /arch:SSE2 für Code ausspuckt...EDIT: OK, erster schneller Test negativ: MSVC 2008/2010 verwenden trotz /arch:SSE2 Switch statt SSE2 lieber 32 Bit Registerpaare und die dadurch nötigen mit-der-Kirche-ums-Kreuz Multiplikationen und Divisionen.
-
Hab ein wenig rumgebastelt und eine Schleife mit SSE-Funktion und eine normale verwendet:
for(int i=0;i<20000000;i++){ f[i] = _mm_andnot_si128(d[i],e); } for(int i=0;i<20000000;i++){ c[i] = a[i] & (!b); c2[i] = a2[i] & (!b2); }Eigentlich sollte die obere Schleife deutlich schneller sein, aber mit aktivierter Codeoptimierung ist sogar die untere schneller.
Auch ändert sich nichts, wenn ich SSE2 aktiviere/deaktiviere
-
Müsste das nicht eher so heissen?
for(int i=0;i<20000000;i++){ c[i] = (~a[i]) & b; c2[i] = (~a2[i]) & b2; }