正在加载视频...

视频加载失败

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 次观看 • 9 天前 •via X (Twitter)

23 条评论

tetsuo 的头像
tetsuo9 天前

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.

Frederico Pissarra 的头像
Frederico Pissarra9 天前

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`.

tetsuo 的头像
tetsuo9 天前

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 😄

Frederico Pissarra 的头像
Frederico Pissarra9 天前

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!

tetsuo 的头像
tetsuo9 天前

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

Frederico Pissarra 的头像
Frederico Pissarra9 天前

As always, this is an AWESOME analysis...

Traveler 的头像
Traveler8 天前

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.

X Girls 的头像
X Girls9 天前

woah 🤯

why 的头像
why9 天前

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.

patrick mcqueeny 的头像
patrick mcqueeny9 天前

interesting! but why?

Andrew 的头像
Andrew9 天前

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

Wow Cool Thanks 的头像
Wow Cool Thanks8 天前

NOTHING ELSE MATTERS UNLESS STRAFE JUMP GIVES ME ACCELERATION.

MancerAI 的头像
MancerAI8 天前

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

ai(Key)骆驼 的头像
ai(Key)骆驼8 天前

Good

ヴァルカン 的头像
ヴァルカン8 天前

how do you make these vids? cool

Ben 的头像
Ben8 天前

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

Time 的头像
Time8 天前

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

Necati Demir, PhD 的头像
Necati Demir, PhD8 天前

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

Pollino Geroni 的头像
Pollino Geroni9 天前

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

A. I. (Macro Photography)🔬 的头像
A. I. (Macro Photography)🔬9 天前

Magic.

Bill Crowell 的头像
Bill Crowell8 天前

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

Charles Waters 的头像
Charles Waters8 天前

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.

Orion Night 的头像
Orion Night9 天前

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

相关视频