4 ms·
Yes, but that converts to 128 bits before doing the actual sum (maybe the compiler can still optimize that away?) My idea was a better language where typecasts
by rep_lodsb 4y ago
Yes, but that converts to 128 bits before doing the actual sum (maybe the compiler can still optimize that away?)
My idea was a better language where typecasts are never needed at all, because the compiler knows how the result will be used (in this example, returned as int64_t), and can produce whatever code is most efficient and either produces the correct result or a runtime exception.
edit:
Also any non-toy compiler will optimize division by powers of two into a shift operation, so ChatGPT isn't being clever at all here, just repeating a common superstition.
- jlokier 4y agoChatGPT knows better! > ChatGPT isn't being clever at all here, just repeating a common superstition Source: #include <stdint.h> int64_t midpoint_ChatGPT(int64_t a, int64_t b) { __int128 sum = (__int128) a + (__int128) b; // Shift the sum to the right by 1 bit to divide it by 2 // and get the midpoint. This operation is equivalent to // sum / 2, but is more efficient because it uses a bit shift // operation instead of a division operation. int64_t midpoint = (int64_t) (sum >> 1); return midpoint; } int64_t midpoint_rep_lodsb(int64_t a, int64_t b) { __int128 sum = (__int128) a + (__int128) b; // Shifts are for the superstitious. int64_t midpoint = (int64_t) (sum / 2); return midpoint; } Clang -O2 output: _midpoint_ChatGPT: pushq %rbp movq %rsp, %rbp movq %rdi, %rcx sarq $63, %rcx movq %rsi, %rax sarq $63, %rax addq %rdi, %rsi adcq %rcx, %rax shldq $63, %rsi, %rax popq %rbp retq _midpoint_rep_lodsb: pushq %rbp movq %rsp, %rbp movq %rdi, %rcx sarq $63, %rcx movq %rsi, %rax sarq $63, %rax addq %rdi, %rsi adcq %rcx, %rax movq %rax, %rcx shrq $63, %rcx addq %rsi, %rcx adcq $0, %rax shldq $63, %rcx, %rax popq %rbp retq GCC -O2 output: midpoint_ChatGPT: endbr64 movq %rsi, %r8 movq %rdi, %rax sarq $63, %rdi sarq $63, %rsi movq %rdi, %rdx addq %r8, %rax adcq %rsi, %rdx shrdq $1, %rdx, %rax ret midpoint_rep_lodsb: endbr64 movq %rsi, %rcx movq %rdi, %rax sarq $63, %rdi sarq $63, %rcx movq %rdi, %rdx addq %rax, %rsi movq %rcx, %rdi adcq %rdx, %rdi xorl %edx, %edx movq %rdi, %rcx shrq $63, %rcx movq %rcx, %rax addq %rsi, %rax adcq %rdi, %rdx shrdq $1, %rdx, %rax ret
- rep_lodsb 4y agoBut all of these use a bit shift instead of the (I)DIV instruction. I wasn't saying compilers can't be stupid, but the AI-generated comment explicitly stated that the shift operation was more efficient than division, not that it would result in fewer instructions emitted. midpoint_rep_lodsb_handwritten: endbr64 movq $0x8000000000000000, %rax xorq %rax, %rsi ;convert two's complement to biased xorq %rax, %rdi addq %rsi, %rdi rcrq $1, %rdi xorq %rdi, %rax ;convert back ret (sorry if I got the syntax wrong, AT&T is just horrible)