Heim > Backend-Entwicklung > C++ > Wie können Vektorisierungstechniken verwendet werden, um die Konvertierung einer IPv4-Adresse von einer Zeichenfolge in eine Ganzzahl zu beschleunigen?

Wie können Vektorisierungstechniken verwendet werden, um die Konvertierung einer IPv4-Adresse von einer Zeichenfolge in eine Ganzzahl zu beschleunigen?

DDD
Freigeben: 2024-11-15 16:49:03
Original
589 Leute haben es durchsucht

How can vectorization techniques be used to accelerate the conversion of an IPv4 address from a string to an integer?

Schnellste Möglichkeit, eine IPv4-Adresse aus einer Zeichenfolge zu erhalten

Ursprünglicher Code in Frage:

UINT32 GetIP(const char *p)
{
    UINT32 dwIP=0,dwIP_Part=0;
    while(true)
    {
        if(p[0] == 0)
        {
            dwIP = (dwIP << 8) | dwIP_Part;
            break;
        }
        if(p[0]=='.') 
        {       
            dwIP = (dwIP << 8) | dwIP_Part;                     
            dwIP_Part = 0;
           p++;
        }
        dwIP_Part = (dwIP_Part*10)+(p[0]-'0');
        p++;
    }
    return dwIP;
}
Nach dem Login kopieren

Schnellere vektorisierte Lösung:

Verwendung der x86-Befehlssatz, eine effizientere Lösung des Problems wird unten vorgestellt:

UINT32 MyGetIP(const char *str) {
    // Load and convert input
    __m128i input = _mm_lddqu_si128((const __m128i*)str);
    input = _mm_sub_epi8(input, _mm_set1_epi8('0'));

    // Generate shuffled array
    __m128i cmp = input;
    UINT32 mask = _mm_movemask_epi8(cmp);
    __m128i shuf = shuffleTable[mask];
    __m128i arr = _mm_shuffle_epi8(input, shuf);

    // Calculate coefficients
    __m128i coeffs = _mm_set_epi8(0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1, 0, 100, 10, 1);

    // Multiply and accumulate
    __m128i prod = _mm_maddubs_epi16(coeffs, arr);
    prod = _mm_hadd_epi16(prod, prod);

    // Reorder result
    __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);

    // Extract result
    return _mm_extract_epi32(prod, 0);
}
Nach dem Login kopieren

Vorberechnung der ShuffleTable:

void MyInit() {
    int len[4];
    for (len[0] = 1; len[0] <= 3; len[0]++)
        for (len[1] = 1; len[1] <= 3; len[1]++)
            for (len[2] = 1; len[2] <= 3; len[2]++)
                for (len[3] = 1; len[3] <= 3; len[3]++) {
                    int slen = len[0] + len[1] + len[2] + len[3] + 4;
                    int rem = 16 - slen;
                    for (int rmask = 0; rmask < 1<<rem; rmask++) {
                        int mask = 0;
                        char shuf[16] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
                        int pos = 0;
                        for (int i = 0; i < 4; i++) {
                            for (int j = 0; j < len[i]; j++) {
                                shuf[(3-i) * 4 + (len[i]-1-j)] = pos;
                                pos++;
                            }
                            mask ^= (1<<pos);
                            pos++;
                        }
                        mask ^= (rmask<<slen);
                        _mm_store_si128(&amp;shuffleTable[mask], _mm_loadu_si128((__m128i*)shuf));
                    }
                }
}
Nach dem Login kopieren

Auswertung:

Diese Lösung ist aufgrund von Vektorisierungstechniken deutlich schneller und übertrifft den Originalcode um das 7,8-fache. Es kann etwa 336 Millionen IP-Adressen pro Sekunde auf einem einzigen Kern eines 3,4-GHz-Prozessors verarbeiten.

Das obige ist der detaillierte Inhalt vonWie können Vektorisierungstechniken verwendet werden, um die Konvertierung einer IPv4-Adresse von einer Zeichenfolge in eine Ganzzahl zu beschleunigen?. 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