[opt]function use sse to opt match_ipv6_subnet (#38755) (#43513)

## Proposed changes
https://github.com/apache/doris/pull/38755
test
```
-------------------------------------------------------------------
Benchmark                         Time             CPU   Iterations
-------------------------------------------------------------------
BM_matchIPv6SubnetSSE          1.89 ns         1.89 ns   1000000000
BM_matchIPv6SubnetNative       4.99 ns         4.99 ns    561455254
```
This commit is contained in:
Mryange
2024-11-11 18:59:35 +08:00
committed by GitHub
parent 55133f8e61
commit dc9ec5b177

View File

@ -20,8 +20,8 @@
#pragma once
#include "util/sse_util.hpp"
#include "vec/common/format_ip.h"
namespace doris {
class IPAddressVariant {
@ -73,6 +73,29 @@ bool match_ipv4_subnet(uint32_t addr, uint32_t cidr_addr, uint8_t prefix) {
return (addr & mask) == (cidr_addr & mask);
}
#if defined(__SSE2__) || defined(__aarch64__)
bool match_ipv6_subnet(const uint8_t* addr, const uint8_t* cidr_addr, uint8_t prefix) {
uint16_t mask = _mm_movemask_epi8(
_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_cast<const __m128i*>(addr)),
_mm_loadu_si128(reinterpret_cast<const __m128i*>(cidr_addr))));
mask = ~mask;
if (mask) {
const auto offset = std::countl_zero(mask);
if (prefix / 8 != offset) {
return prefix / 8 < offset;
}
auto cmpmask = ~(0xff >> (prefix % 8));
return (addr[IPV6_BINARY_LENGTH - 1 - offset] & cmpmask) ==
(cidr_addr[IPV6_BINARY_LENGTH - 1 - offset] & cmpmask);
} else {
// All the bytes are equal.
}
return true;
}
#else
// ipv6 liitle-endian input
bool match_ipv6_subnet(const uint8_t* addr, const uint8_t* cidr_addr, uint8_t prefix) {
if (prefix > IPV6_BINARY_LENGTH * 8U) {
@ -93,6 +116,7 @@ bool match_ipv6_subnet(const uint8_t* addr, const uint8_t* cidr_addr, uint8_t pr
auto mask = ~(0xff >> prefix);
return (addr[i] & mask) == (cidr_addr[i] & mask);
}
#endif
IPAddressCIDR parse_ip_with_cidr(std::string_view cidr_str) {
size_t pos_slash = cidr_str.find('/');