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
Patricia ArquetteOriginal
2024-11-17 07:35:04575Durchsuche

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
}

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!

Stellungnahme:
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