Live data from Hacker News

John Carmack on inlined code (2014)

number-none.com

251–260 of 402 posts

Re: John Carmack on inlined code (2014)

#251

Earlier quoted context omitted.

To be fair, back in 2014 that was one frame at 60Hz or slower for some titles. At 80-120Hz, 3-5 frames is comparatively similar time.

I've heard that a good reaction time is around 200 ms, some experiments seem to confirm this figure [1]. At 60Hz, a frame is displayed every 17 ms. So it would take a 12 frames animation and a trained gamer for a couple of frames to make a difference (e.g. push the right button before the animation ends and the opponent's action takes effect). [1] https://humanbenchmark.com/tests/reactiontime/statistics

Reaction time is completely different to the input latency Carmack is worrying about in his scenario. Imagine if you thought I'm going to move my arm, and 200ms later your arm actually moved. Apply the same to a first-person shooter --- imagine you nudge your mouse slightly, and 200ms later you get some movement on screen. That is ___hugely___ noticeable.

Re: John Carmack on inlined code (2014)

#254
post #249

Related: John Carmack on Inlined Code - https://news.ycombinator.com/item?id=39008678 - Jan 2024 (2 comments) John Carmack on Inlined Code (2014) - https://news.ycombinator.com/item?id=33679163 - Nov 2022 (1 comment) John Carmack on Inlined Code (2014) - https://news.ycombinator.com/item?id=25263488 - Dec 2020 (169 comments) John Carmack on Inlined Code (2014) - https://news.ycombinator.com/item?id=18959636 - Jan 201…

There is a longer version of this thought-provoking post, also including Carmack's thoughts in 02012, at https://cbarrete.com/carmack.html. But maybe that version has not also had threads about it.

Re: John Carmack on inlined code (2014)

#255

Earlier quoted context omitted.

To be fair, back in 2014 that was one frame at 60Hz or slower for some titles. At 80-120Hz, 3-5 frames is comparatively similar time.

Why would you even bother running at a game at 120Hz if the user's response to what's being drawn is effectively 24-30 FPS?

You've seen games running at 120Hz and at 60Hz. The difference is obvious, isn't it? The difference between 24Hz and 60Hz is certainly obvious: that's the visual difference between movies and TV sitcoms.

I can type about 90 words per minute on QWERTY, which is about 8 keystrokes per second. That means that the average interval between keystrokes is about 120 milliseconds, already significantly less than my 200-millisecond reaction time, and many keystrokes are closer together than that—but I rarely make typographical errors. Fast typists can hit 150 words per minute. Performing musicians consistently nail note timing to within about 40 milliseconds. So it turns out that people do routinely time their physical movements a lot more precisely than their reaction time. Their jitter is much lower than their latency, a phenomenon you are surely familiar with in other contexts, such as netcode for games.

If someone's latency is 200 milliseconds but its jitter (measured as standard deviation) is 10 milliseconds, then reducing the frame latency from a worst-case 16.7 milliseconds (or 33.3 milliseconds in your 30Hz example) to a worst-case 8.3 milliseconds, and average-case 8.3 milliseconds to average-case 4.2 milliseconds, you're knocking off a whole 0.42 standard deviations off their latency. If they're playing against someone else with the same latency, that 0.42σ advantage is very significant! I think they'll win almost 61% of the time, but I'm not sure of my statistics†.

See also https://danluu.com/input-lag/#appendix-why-measure-latency:

> Latency matters! For very simple tasks, people can perceive latencies down to 2 ms or less. Moreover, increasing latency is not only noticeable to users, it causes users to execute simple tasks less accurately. If you want a visual demonstration of what latency looks like and you don’t have a super-fast old computer lying around, check out this MSR demo on touchscreen latency.

> The most commonly cited document on response time is the nielsen group[sic] article on response times, which claims that latncies[sic] below 100ms feel equivalent and perceived[sic] as instantaneous. One easy way to see that this is false is to go into your terminal and try sleep 0; echo "pong" vs. sleep 0.1; echo "test" (or for that matter, try playing an old game that doesn't have latency compensation, like quake 1, with 100 ms ping, or even 30 ms ping, or try typing in a terminal with 30 ms ping). For more info on this and other latency fallacies, see this document on common misconceptions about latency.

(The original contains several links substantiating those claims.)

https://danluu.com/keyboard-latency/#appendix-counter-argume... has a longer explanation.

______

† First I tried sum(rnorm(100000) σ of latency being added; it's a random latency of up to 0.83σ, so I tried sum(rnorm(100000) rnorm(100000) + runif(100000, max=0.83))/1000, we get more like a 60.8% chance that the 120fps player will out-twitch them. I'm sure someone who actually knows statistics can tell me the correct way to model this to get the right answer in closed form, but I'm not sure I could tell the correct closed-form formula from an incorrect one, so I resorted to brute force.

Re: John Carmack on inlined code (2014)

#256
Interesting: this is a 2014 post from Jonathan Blow reproducing a 2014 comment by John Carmack reproducing a 2007 e-mail by the same Carmack reproducing a 2006 conversation (I assume also via e-mail) he had with a Henry Spencer reproducing something else the same Spencer read a while ago and was trying to remember (possibly inaccurately?).

I wonder what is the actual original source (from Saab, maybe?), and if this indeed holds true?

Re: John Carmack on inlined code (2014)

#257

How does a program work when its disallow "backward branches". Same thing with "subroutine calls" how do you structure a program without them?

Well, you have one backward branch at the end of the program, and you inline your subroutines. I'm pretty sure you've written shaders for ancient GPUs that had similar limitations? And anything you can do in hardware you can do without subroutine calls, and in hardware the loop starts again on every clock cycle.

Re: John Carmack on inlined code (2014)

#258

Earlier quoted context omitted.

> protocols, conventions, failsafes, QA teams, etc, etc that are either still hugely difficult to contribute to (Linux kernel, web browsers, etc) To be fair here, I don't think it's reasonable to expect that once you have "software development skills" it automatically gives you the ability to fix any code out there. The Linux Kernel and web browsers are not hard to contribute to because of conventions, they're hard b…

There are multiple reasons that contributing to various projects may be difficult. But, I was replying to a specific comment about writing code in a way that is easy to understand, and the comment author's acknowledgement that this idea/practice is hard to scale to a large number of developers (presumably because everyone's skills are different and because we each have different ideas about what is "clear", etc). So,…

> Yet, even a very competent C++ dev is going to have a ton of trouble figuring out the Chromium code base.

I don't think this is true, or at least it wasn't circa 2018 when I was writing C++ professionally and semi-competently. I sometimes had to read, understand and change parts of the Chromium code base since I was working on a component which integrated CEF. Over time I began to think of Chromium as a good reference for how to maintain a well-organized C++ code base. It's remarkably plain and understandable, greppable even. Eventually I was able to contribute a patch or two back to CEF.

The hardest thing by far with respect to making those contributions wasn't understanding the C++, it was understanding how to work the build system for development tasks.

Re: John Carmack on inlined code (2014)

#259

Earlier quoted context omitted.

I've heard that a good reaction time is around 200 ms, some experiments seem to confirm this figure [1]. At 60Hz, a frame is displayed every 17 ms. So it would take a 12 frames animation and a trained gamer for a couple of frames to make a difference (e.g. push the right button before the animation ends and the opponent's action takes effect). [1] https://humanbenchmark.com/tests/reactiontime/statistics

I'm not sure this is the right way to look at it. I can't find stats right now, but I recall reading top players making frame-perfect moves in games like Smash Bros. Melee and Rocket League.

The mistake with focusing on reaction time is that humans can anticipate actions and can perform complex sequences of actions pretty quickly (we have two hands and 10 fingers). So someone playing one of those "test your reaction time" games might only score like 30ms. But someone playing a musical instrument can still play a 64th note at 120BPM.

Imagine playing a drum that took between 0 and 5 extra frames at 60FPS between striking the head and it producing a sound. Most people would notice that kind of delay, even if they can't "react" that quickly.

In games, frame delay translates to having to hold down a key (or wait before pressing the next one) for longer than is strickly necessary in order to produce an effect. Since fighting games are all about key sequences, the difference between needing to hold key for 0 frames and 5 frames is massive when you consider key combinations might be sequences of up to 5 key presses. 5 frames of delay x five sequential key presses x 8ms a frame = 1600ms vs 1 frame x 5 seq. key presses x 8ms = 40ms.

There's a massive difference between taking 1.6s to execute a complex move and 0.040s.

Re: John Carmack on inlined code (2014)

#260

How does a program work when its disallow "backward branches". Same thing with "subroutine calls" how do you structure a program without them?

You can do a lot with a program that looks like:

  while(1) {
    if (condition1)
      ...
    if (condition2)
      ...
    // etc
  }
Subroutine calls can be eliminated by inlining everything, using macros to make the code more manageable. Loops can be simulated using macros that expand to multiple copies of the code, one for each step.

One advantage is that the program will never get into an unbounded loop because the program counter will always advance towards the end of the main loop.

Post reply on HN