Heim > Backend-Entwicklung > C++ > Wie können wir mit SSE2 effizient zwischen Doppelzahlen und 64-Bit-Ganzzahlen konvertieren?

Wie können wir mit SSE2 effizient zwischen Doppelzahlen und 64-Bit-Ganzzahlen konvertieren?

DDD
Freigeben: 2024-12-04 10:55:11
Original
975 Leute haben es durchsucht

How Can We Efficiently Convert Between Doubles and 64-bit Integers Using SSE2?

Effiziente Double/Int64-Konvertierungen ohne AVX512

SSE2 bietet Anweisungen zum Konvertieren zwischen Gleitkommazahlen und 32-Bit-Ganzzahlen, es fehlen jedoch Äquivalente zum Konvertieren dazwischen Doubles und 64-Bit-Ganzzahlen. Wie können wir solche Konvertierungen effizient simulieren?

Cut-Corners-Konvertierungen

Wenn Bereichseinschränkungen akzeptabel sind, können die folgenden Tricks Konvertierungen in nur zwei Anweisungen durchführen:

Doppelt zu Int64

__m128i double_to_int64(__m128d x) {
    x = _mm_add_pd(x, _mm_set1_pd(0x0018000000000000));
    return _mm_sub_epi64(_mm_castpd_si128(x), _mm_castpd_si128(_mm_set1_pd(0x0018000000000000)));
}
Nach dem Login kopieren

Double zu UInt64

__m128i double_to_uint64(__m128d x){
    x = _mm_add_pd(x, _mm_set1_pd(0x0010000000000000));
    return _mm_xor_si128(_mm_castpd_si128(x), _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)));
}
Nach dem Login kopieren

Int64 zu Double

__m128d int64_to_double(__m128i x){
    x = _mm_add_epi64(x, _mm_castpd_si128(_mm_set1_pd(0x0018000000000000)));
    return _mm_sub_pd(_mm_castsi128_pd(x), _mm_set1_pd(0x0018000000000000));
}
Nach dem Login kopieren

UInt64 bis Double

__m128d uint64_to_double(__m128i x){
    x = _mm_or_si128(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)));
    return _mm_sub_pd(_mm_castsi128_pd(x), _mm_set1_pd(0x0010000000000000));
}
Nach dem Login kopieren

Vollbereichskonvertierungen

Für Konvertierungen, die den gesamten Bereich von 64-Bit-Ganzzahlen verarbeiten, finden Sie hier optimierte Implementierungen:

UInt64 bis Double

__m128d uint64_to_double_full(__m128i x){
    __m128i xH = _mm_srli_epi64(x, 32);
    xH = _mm_or_si128(xH, _mm_castpd_si128(_mm_set1_pd(19342813113834066795298816.)));          //  2^84
    __m128i xL = _mm_blend_epi16(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)), 0xcc);   //  2^52
    __m128d f = _mm_sub_pd(_mm_castsi128_pd(xH), _mm_set1_pd(19342813118337666422669312.));     //  2^84 + 2^52
    return _mm_add_pd(f, _mm_castsi128_pd(xL));
}
Nach dem Login kopieren

Int64 zu Double

__m128d int64_to_double_full(__m128i x){
    __m128i xH = _mm_srai_epi32(x, 16);
    xH = _mm_blend_epi16(xH, _mm_setzero_si128(), 0x33);
    xH = _mm_add_epi64(xH, _mm_castpd_si128(_mm_set1_pd(442721857769029238784.)));              //  3*2^67
    __m128i xL = _mm_blend_epi16(x, _mm_castpd_si128(_mm_set1_pd(0x0010000000000000)), 0x88);   //  2^52
    __m128d f = _mm_sub_pd(_mm_castsi128_pd(xH), _mm_set1_pd(442726361368656609280.));          //  3*2^67 + 2^52
    return _mm_add_pd(f, _mm_castsi128_pd(xL));
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie können wir mit SSE2 effizient zwischen Doppelzahlen und 64-Bit-Ganzzahlen konvertieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage