Video wird geladen...

Video konnte nicht geladen werden

Zur Startseite

I compiled Quake III's fast inverse square root on 64-bit Linux with gcc -O1 and it returned negative numbers. The long cast reads past the float into the stack, and the low bit of the return address ends up in the sign bit.

32,321 Aufrufe • vor 9 Tagen •via X (Twitter)

23 Kommentare

Profilbild von tetsuo
tetsuovor 9 Tagen

Quake III's Q_rsqrt as shipped, on 64-bit Linux. gcc -O1 q.c -o q && ./q gcc 13 prints -0.499154. clang 18 -O1 prints 0.000000, because reading 8 bytes from a 4-byte float is undefined behavior and clang compiles Q_rsqrt to a single ret. Your result depends on your compiler version.

Profilbild von Frederico Pissarra
Frederico Pissarravor 9 Tagen

x86-64 SysV ABI? If that is the case `long int` is 64 bits long, not 32... maybe this is the reason. Change `long int` to `int`.

Profilbild von tetsuo
tetsuovor 9 Tagen

Yep, that's the bug. On x86-64 SysV long is 8 bytes so *(long *)&y reads 4 bytes past y into the stack. The fix is at ~10:30 you went straight to the replies 😄

Profilbild von Frederico Pissarra
Frederico Pissarravor 9 Tagen

Yep... I've got straight to the replies (sorry!) and watched the video now... as said before, always an AMAZING analysis. I wish I had the patience and skills to do amazing videos like this one!

Profilbild von tetsuo
tetsuovor 9 Tagen

I'll jump on discord this weekend and give you my work flow.

Profilbild von Frederico Pissarra
Frederico Pissarravor 9 Tagen

As always, this is an AWESOME analysis...

Profilbild von Traveler
Travelervor 8 Tagen

Quake III was made in 1999. For 32-bit CPU. So kids, if you think using explicit types like uin32_t,uin64_t,int32_t,int64_t and co is just meaningless old farts fad then you are in a world of pain if you try porting shit from 1981 to 2002 or so (AMD Opteron in 2003 was first x86 compatible 64-bit CPU) to modern day.

Profilbild von X Girls
X Girlsvor 9 Tagen

woah 🤯

Profilbild von why
whyvor 9 Tagen

A perfect example of code that was “clever” on 32-bit and undefined on 64-bit. `long` being 8 bytes turns that type pun into an out-of-bounds read.

Profilbild von patrick mcqueeny
patrick mcqueenyvor 9 Tagen

interesting! but why?

Profilbild von Andrew
Andrewvor 9 Tagen

Ya ..W/e use like Java script or something

Profilbild von Wow Cool Thanks
Wow Cool Thanksvor 8 Tagen

NOTHING ELSE MATTERS UNLESS STRAFE JUMP GIVES ME ACCELERATION.

Profilbild von MancerAI
MancerAIvor 8 Tagen

I understand this is mostly out of curiosity, so maybe a stupid comment but; doesn't modern CPUs have fast inverse square root built in/as an OP

Profilbild von ai(Key)骆驼
ai(Key)骆驼vor 8 Tagen

Good

Profilbild von ヴァルカン
ヴァルカンvor 8 Tagen

how do you make these vids? cool

Profilbild von Ben
Benvor 8 Tagen

Yep that one also drove me nuts, genius math in the game.

Profilbild von Time
Timevor 8 Tagen

てつお!元気?何言ってるのか全くわからない😊✨

Profilbild von Necati Demir, PhD
Necati Demir, PhDvor 8 Tagen

Just curious. Did you generate this visualization with Opus 5.5? If so that looks great.

Profilbild von Pollino Geroni
Pollino Geronivor 9 Tagen

@grok sono ignorante a cosa servirebbe quello che l’Op ha fatto?

Profilbild von A. I. (Macro Photography)🔬
A. I. (Macro Photography)🔬vor 9 Tagen

Magic.

Profilbild von Bill Crowell
Bill Crowellvor 8 Tagen

Impressive. I wonder what the performance would be on an alternate function that uses division.

Profilbild von Charles Waters
Charles Watersvor 8 Tagen

I thought that Quake's version of this code was intended to be fast and 'accurate enough' for the games use, but had known limitations and was probably 8 bit? Maybe 16? I wouldn't expect perfect performance from it.

Profilbild von Orion Night
Orion Nightvor 9 Tagen

many such cases. long is 8 bytes on LP64 so the cast reads 4 bytes past the float, straight into whatever junk the frame left there. the magic constant was never the problem, the type punning was

Ähnliche Videos