Your current code for parsing IPv4 addresses is fairly efficient, but it can be further optimized for even greater speed. One approach is to utilize vectorized solutions specifically designed for this task.
For x86 processors supporting SSE4.1 or SSSE3 instructions, here's a vectorized solution that significantly improves performance:
__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 }
To utilize this vectorized solution effectively, it requires a pre-calculated shuffle table, shuffleTable, that can be generated as follows:
void MyInit() { memset(shuffleTable, -1, sizeof(shuffleTable)); 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 rmask = (1<<rem)-1; //note: only maximal rmask is possible if strings are zero-padded 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(&shuffleTable[mask], _mm_loadu_si128((__m128i*)shuf)); } } }
On an Ivy Bridge processor, the vectorized solution demonstrates impressive performance, processing 336 million addresses per second. This is approximately 7.8 times faster than the code provided in the original question.
위 내용은 벡터화된 솔루션을 사용하여 IP 주소 구문 분석 속도를 향상시키는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!