2016-06-01 6 views

Antwort

5

Sie haben einige triviale Fragen gestellt, die Sie beantworten können, indem Sie sich ansehen, wie ein C-Compiler das tut. Von dort aus können Sie die verwendeten Anweisungen nachschlagen und entscheiden, welche Sie tatsächlich verwenden möchten. (Es gibt ungefähr eine Zillion verschiedener Rundungsfunktionen in libm, also ist es nicht immer einfach, die richtige zu wählen).

Mit -O3 -ffast-math werden die meisten einfachen libm-Funktionen inline (da es möglicherweise errno auf NaN nicht setzen, oder Mist wie das).

Wie auch immer, Compiler und -ausgabe, von gcc 5.3 on the Godbolt Compiler Explorer:

#include <math.h> 

int floor_double(double x) { return (int) floor(x); } 
    roundsd xmm0, xmm0, 9 
    cvttsd2si  eax, xmm0 
    ret 

int truncate_double(double x) { return (int)x; } 
    cvttsd2si  eax, xmm0 
    ret 

Siehe Tag Wiki für Links zu Intel-Befehlssatz Referenzhandbuch pdf. Es gibt auch eine unofficial HTML version generiert aus der PDF.

cvttsd2si truncates towards zero, wie trunc(), statt Rundung in Richtung -Infinity wie die floor() function.

Deshalb kompiliert floor() zu SSE4.1 roundsd, wenn dieser Befehlssatz verfügbar ist. (Ansonsten muss man mit dem Rundungsmodus herumspielen, wie man sieht, wenn man die Option -march auf godbolt entfernt oder ändert).


Es gibt auch gepackte Versionen der Konvertierungsbefehle, wie CVTTPD2DQ` 2 auf einmal zu tun. (Oder 4 mit AVX).

0

Zum Doppelboden verwenden CVTTPD2DQ—Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers.

CVTTPD2DQ does floor/trunkate zwei double s zu zwei int s in einem XMM-Register.

Die entsprechende Intel C/C++ Compiler Intrinsic ist

____m128i _mm_cvttpd_epi32(__m128d a) 

Um das Ergebnis zu einem GPR (General Purpose Register) wie EAX zu setzen, können Sie die folgenden Anweisungen verwenden können:

CVTTPD2DQ xmm0, xmm1 ; XMM1 is the source of doubles 
movd eax, xmm0  ; extracts int(0) from XMM0 to EAX 
pextrd ecx, xmm0, 1 ; extracts int(1) from XMM0 to ECX 
+0

Wie kann ich dann das Ergebnis von xmm in f.e. EAX registrieren? – formateu

+1

@formateu: Ich habe meine Antwort aktualisiert. – zx485

+0

zx485: Wenn das int passen in eax registrieren, wird movd eax, xmm0 den Job tun? – formateu

Verwandte Themen