Heim > Backend-Entwicklung > C++ > Gibt es eine schnellere Möglichkeit, IPv4-Adressen von Zeichenfolgen in Ganzzahlen umzuwandeln?

Gibt es eine schnellere Möglichkeit, IPv4-Adressen von Zeichenfolgen in Ganzzahlen umzuwandeln?

Patricia Arquette
Freigeben: 2024-11-17 07:35:04
Original
577 Leute haben es durchsucht

Is There a Faster Way to Convert IPv4 Addresses from Strings to Integers?

Eine effiziente Alternative zum Konvertieren von IPv4-Adressen aus Strings

F: Erhöhung der Geschwindigkeit der IPv4-Adressanalyse aus Strings

Bestehende Lösungen zum Parsen von IPv4-Adressen aus Zeichenfolgen können langsam sein und den Durchsatz einschränken. Gibt es eine schnellere Methode oder eine praktikable Alternative?

A: Eine vektorisierte Lösung mit SSE4.1

Übersicht

Um die Parsing-Leistung zu maximieren, bietet eine vektorisierte Lösung, die SSE4.1-Anweisungen nutzt, erhebliche Geschwindigkeitsvorteile:

Code

__m128i shuffleTable[65536];    //can be reduced 256x times, see @IwillnotexistIdonotexist

UINT32 MyGetIP(const char *str) {
    __m128i input = _mm_lddqu_si128((const __m128i*)str);   //"192.167.1.3"
    input = _mm_sub_epi8(input, _mm_set1_epi8('0'));        //1 9 2 254 1 6 7 254 1 254 3 208 245 0 8 40 
    __m128i cmp = input;                                    //...X...X.X.XX...  (signs)
    UINT32 mask = _mm_movemask_epi8(cmp);                   //6792 - magic index
    __m128i shuf = shuffleTable[mask];                      //10 -1 -1 -1 8 -1 -1 -1 6 5 4 -1 2 1 0 -1 
    __m128i arr = _mm_shuffle_epi8(input, shuf);            //3 0 0 0 | 1 0 0 0 | 7 6 1 0 | 2 9 1 0 
    __m128i coeffs = _mm_set_epi8(0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1);
    __m128i prod = _mm_maddubs_epi16(coeffs, arr);          //3 0 | 1 0 | 67 100 | 92 100 
    prod = _mm_hadd_epi16(prod, prod);                      //3 | 1 | 167 | 192 | ? | ? | ? | ?
    __m128i imm = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 4, 2, 0);
    prod = _mm_shuffle_epi8(prod, imm);                     //3 1 167 192 0 0 0 0 0 0 0 0 0 0 0 0
    return _mm_extract_epi32(prod, 0);
//  return (UINT32(_mm_extract_epi16(prod, 1)) << 16) + UINT32(_mm_extract_epi16(prod, 0)); //no SSE 4.1
}
Nach dem Login kopieren

Vorteile:

  • 7,8-mal schneller als der Originalcode.
  • Verarbeitet über 300 Millionen Adressen pro Sekunde (Single Core, 3,4 GHz).
  • Nutzt vektorisierte Anweisungen für maximalen Durchsatz.

Zusätzliche Hinweise:

  • Die ShuffleTable erfordert eine Vorberechnung.
  • Geänderter Code von @IwillnotexistIdonotexist reduziert die ShuffleTable-Größe auf 4 KB leichte Leistungseinbußen.

Das obige ist der detaillierte Inhalt vonGibt es eine schnellere Möglichkeit, IPv4-Adressen von Zeichenfolgen in Ganzzahlen umzuwandeln?. 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