5 ms·
That code might produce two byte reads and a shift and the bitwise-or to reformulate the 16 bit value in memory . In the original code the 16 bit read feeds di
by petermcneeley 8y ago
That code might produce two byte reads and a shift and the bitwise-or to reformulate the 16 bit value in memory . In the original code the 16 bit read feeds directly into the lookup table.
- amluto 8y agoThe compiler always might produce garbage. But a decent compiler won't: #include <stddef.h> #include <stdint.h> uint16_t read_2byte_le(const uint8_t *src) { return (uint16_t)(src[0] | ((uint16_t)(src[1]) << 8)); } This generates the correct code with gcc and with clang. Sadly, clang is a bit fragile in this regard: https://bugs.llvm.org/show_bug.cgi?id=39438 https://bugs.llvm.org/show_bug.cgi?id=39438
- petermcneeley 8y agoEven more sadly, msvc produces this type of asm: lea r10,[r10+8] shl rcx,8 or rcx,rax shl r9,8 movzx eax,byte ptr [r10-8] shl rax,8 or rdx,rax shl r8,8 etc
- amluto 8y agoIs msvc a serious target any more? I have the impression that it’s kind of deprecated in favor of clang.
- pianoben 8y agoMSVC supports the Clang front-end, but its optimizer and backend are absolutely not deprecated, as far as I can tell (Microsoft employee here, opinions are my own, no private info disclosed here, etc).
- MaulingMonkey 8y agoClang doesn't have support for C++/CLI (.NET Interop) nor C++/CX (newfangled COM for Windows 8/10 APIs) AFAIK, so that's already two targets where clang isn't even an option[1], nevermind to the point of deprecating MSVC or supplanting it as a default. Similarly, I've yet to see a gamedev codebase that doesn't use MSVC as the primary compiler for Windows builds. [1] Technically you can consume C++/CX APIs as straight up COM in vanilla C++ but that's really not the intention, nor necessarily supported for some things.
- cesarb 8y agoWould a memcpy into a uint16_t be less fragile?
- pjscott 8y agoJust tried this with godbolt.org and yes, the memcpy() thing is consistently good while the shift-and-or version often gets an unoptimized implementation (depending on compiler and version).
- beached_whale 8y agoIn C++, not necessarily C, memcpy is how you type pun. Seeing as they often are the same compiler it's probably the fastest way.
- amluto 8y agoIIRC memcpy is borderline UB here. It also has the same endianness problem.
- amluto 8y agoI suppose I should add: this operation is so common that I’m surprised it’s not part of the language or the standard library.
- unwind 8y agoThe original code was accused of triggering UB. By definition you cannot defend it by saying what it does since that has been claimed to be undefined. Focus on proving it's well-defined, or rewrite it until it is.