3 ms·
Other reason to move them outside of the function: you might want to prepare them in memory in a way that could speed up the comparison further, which would onl
by sparkie 4y ago
Other reason to move them outside of the function: you might want to prepare them in memory in a way that could speed up the comparison further, which would only need to be done once, not each time the function is called. For example, using AVX_512:
uint64_t protos[8] = {
string_to_uint64("https\0\0\0"),
string_to_uint64("http\0\0\0\0"),
string_to_uint64("file\0\0\0\0"),
string_to_uint64("ftp\0\0\0\0\0"),
string_to_uint64("wss\0\0\0\0\0"),
string_to_uint64("ws\0\0\0\0\0\0"),
0,
0
};
bool maybe_faster_is_special(std::string_view input, uint64_t protos[8]) {
__m512i vprotos = __mm512_load_epi64(&protos[0]);
__m512i vinput = __mm512_broadcastq_epi64(string_to_uint64(input));
__mmask8 comparisons = __mm512_cmpeq_epi64_mask(vinput, vprotos);
return (bool)(!_cvtmask8_u32(comparisons));
}
- hnav 4y agoVery nice, how’s the performance?
- sparkie 4y agoNot tested, but should be predictable. Each instrinsic maps to one instruction. Instruction latencies according to uops.info: vmovdqa64 zmm, m512 ; latency<=12 vpbroadcastq zmm, r64 ; latency<=5 vpcmpeqq k, zmm, zmm ; latency=3 kmovb r32, k ; latency<=3 The code is branchless. It will take the same number of cycles regardless of input. This is why it is `maybe_faster`. The faster version from the article may be faster for http/https because of short-circuiting behavior, but it would be slower for other protocols due to multiple branching. Aside from having greater throughput per instruction, being branchless means you will not have any branch prediction misses which negatively affect performance. The vectorized version would be a significant improvement if there are many (more than 6) small strings to compare, but for this example the difference is probably minor.