Heim > Backend-Entwicklung > C++ > Wie kann ich mithilfe von SSE/AVX-Anweisungen effizient zwischen Gleitkommazahlen mit doppelter Genauigkeit und 64-Bit-Ganzzahlen konvertieren?

Wie kann ich mithilfe von SSE/AVX-Anweisungen effizient zwischen Gleitkommazahlen mit doppelter Genauigkeit und 64-Bit-Ganzzahlen konvertieren?

Barbara Streisand
Freigeben: 2024-12-08 03:02:15
Original
466 Leute haben es durchsucht

How Can I Efficiently Convert Between Double-Precision Floats and 64-bit Integers Using SSE/AVX Instructions?

Effiziente Double/int64-Konvertierungen mit SSE/AVX

SSE2 bietet Funktionen für die Konvertierung von Vektoren zwischen Gleitkommazahlen mit einfacher Genauigkeit und 32-Bit-Ganzzahlen. Es fehlen jedoch direkte Gegenstücke für Gleitkommazahlen mit doppelter Genauigkeit und 64-Bit-Ganzzahlen. AVX bietet diese Konvertierungen ebenfalls nicht an.

Methoden zur Simulation von Intrinsics

1. Für begrenzte Werte:

Wenn bestimmte Einschränkungen toleriert werden, können Konvertierungen zwischen doubles und int64 mit nur zwei Anweisungen durchgeführt werden:

  • double -> ; uint64_t:

    __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
  • double -> int64_t:

    __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
  • uint64_t -> 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
  • int64_t -> doppelt:

    __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

2. Vollständiger Bereich int64 -> double:

Um den gesamten Bereich von int64 in double zu konvertieren, sind 5 Anweisungen für uint64_t und 6 Anweisungen für int64_t erforderlich:

  • uint64_t -> ; 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_t -> 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

AVX512

AVX512 bietet direkte Konvertierungen in/von 64-Bit-Ganzzahlen, sowohl mit als auch ohne Vorzeichen unterzeichnet. Diese Konvertierungen werden mithilfe von Intrinsics wie _mm512_cvtpd_epi64 und _mm256_cvtpd_epi64 durchgeführt.

Bitte beachten Sie, dass diese Lösungen nicht als vollständiger Code bereitgestellt werden. Vom Leser wird erwartet, dass er sie vervollständigt und bei Bedarf optimiert, um sie an seinen spezifischen Kontext anzupassen.

Das obige ist der detaillierte Inhalt vonWie kann ich mithilfe von SSE/AVX-Anweisungen effizient zwischen Gleitkommazahlen mit doppelter Genauigkeit 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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage