3 ms·
It does not make difference. Just -O1 is enough to convert inline strings to static numbers: https://godbolt.org/z/cThn3dTrn https://godbolt.org/z/cThn3dTrn
by adobrawy 4y ago
It does not make difference. Just -O1 is enough to convert inline strings to static numbers: https://godbolt.org/z/cThn3dTrn https://godbolt.org/z/cThn3dTrn
- Someone 4y agoI don’t think you should count on compilers doing that, especially not if it is easy to do better. The modern way to enforce that would be to write constexpr functions to do the conversions (or not? Are compilers required to evaluate constexpr expressions at compile time, where possible?)
- twic 4y ago> Are compilers required to evaluate constexpr expressions at compile time, where possible? No. But C++20 adds consteval, which does carry that requirement: https://www.modernescpp.com/index.php/c-20-consteval-and-constinit https://www.modernescpp.com/index.php/c-20-consteval-and-con... Well, sort of. It has to produce a constant expression, and in practice the way to do that is to evaluate it at compile-time. But under the as-if rule, a compiler can do what it likes, up to and including producing a binary containing your source code and a copy of gcc, and compiling your entire program when you run it.
- sparkie 4y agoOther 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.