Video yükleniyor...

Video Yüklenemedi

Ana Sayfaya Dön

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 görüntüleme • 9 gün önce •via X (Twitter)

23 Yorum

tetsuo profil fotoğrafı
tetsuo9 gün önce

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 profil fotoğrafı
Frederico Pissarra9 gün önce

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 profil fotoğrafı
tetsuo9 gün önce

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 profil fotoğrafı
Frederico Pissarra9 gün önce

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 profil fotoğrafı
tetsuo9 gün önce

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

Frederico Pissarra profil fotoğrafı
Frederico Pissarra9 gün önce

As always, this is an AWESOME analysis...

Traveler profil fotoğrafı
Traveler8 gün önce

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 profil fotoğrafı
X Girls9 gün önce

woah 🤯

why profil fotoğrafı
why9 gün önce

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 profil fotoğrafı
patrick mcqueeny9 gün önce

interesting! but why?

Andrew profil fotoğrafı
Andrew9 gün önce

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

Wow Cool Thanks profil fotoğrafı
Wow Cool Thanks8 gün önce

NOTHING ELSE MATTERS UNLESS STRAFE JUMP GIVES ME ACCELERATION.

MancerAI profil fotoğrafı
MancerAI9 gün önce

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)骆驼 profil fotoğrafı
ai(Key)骆驼8 gün önce

Good

ヴァルカン profil fotoğrafı
ヴァルカン8 gün önce

how do you make these vids? cool

Ben profil fotoğrafı
Ben8 gün önce

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

Time profil fotoğrafı
Time8 gün önce

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

Necati Demir, PhD profil fotoğrafı
Necati Demir, PhD8 gün önce

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

Pollino Geroni profil fotoğrafı
Pollino Geroni9 gün önce

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

A. I. (Macro Photography)🔬 profil fotoğrafı
A. I. (Macro Photography)🔬9 gün önce

Magic.

Bill Crowell profil fotoğrafı
Bill Crowell8 gün önce

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

Charles Waters profil fotoğrafı
Charles Waters9 gün önce

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 profil fotoğrafı
Orion Night9 gün önce

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

Benzer Videolar