Hacker News new | past | comments | ask | show | jobs | submit login

Maybe if all of the objects just referenced a read only version of the world state, and we copied over the updated version at the end of the frame… Hey, wait a minute...

This sounds like a game development reference that I'm missing. Can anyone explain?




He's referring to the utility of immutable data for solving certain parallelism issues - rather than attempt to coordinate all the code that uses a data structure, you can double-buffer it and queue up the write events for the "next frame" instance.

This is a hugely successful pattern throughout a number of aspects of gaming, graphics being one of the most classic examples. Double-buffered graphics don't suffer as much from tearing and other display artifacts.


> This is a hugely successful pattern throughout a number of aspects of gaming, graphics being one of the most classic examples.

Not really, no. Immutability comes at the cost of performance compared to mutability. The gap is shrinking between the two, but it's still wide enough that using pure immutable structures for frame buffers, shaders and other graphical concepts is simply not an option to write games.

Haskell is interesting in the sense that it doesn't prevent you from using mutable structures (e.g. Lenses, Writer) but it encodes this information in the type system. I'm really curious to read the conclusions that Carmack will draw from his experience but I wouldn't be surprised to read that at the very low levels, mutable structures are just unavoidable for high performance games.

Also, mutable structures accessed by concurrent threads is a problem that's much less difficult than most people claim, and it's often much easier to reason about locks and semaphores than about immutable lazily initialized structures.


I don't know where to start.

> using pure immutable structures for frame buffers, shaders and other graphical concepts is simply not an option to write games.

Seeing as people have written games in Haskell, this is clearly not true.

> Haskell is interesting in the sense that it doesn't prevent you from using mutable structures (e.g. Lenses, Writer)

Lenses and Writer both only use immutable data. It is possible to use actual mutable data in the ST and IO monads.

> but it encodes this information in the type system.

This is true of IO, but not of ST. With ST, runST :: (forall s. ST s a) -> a, hides the effects.

> it's often much easier to reason about locks and semaphores than about immutable lazily initialized structures.

I don't know what you mean by this. In terms of functional correctness, immutable data-strucutures, lazy or otherwise, are much easier to reason about. If you are talking about resource-usage, sure, it's a little harder to reason about lazy data-structures than strict ones, but give me a space leak over a race condition to track down any day.


It’ll be interesting to see how the performance issues play out, no? In order to get reliable memory behaviour, you still have to go through a certain amount of voodoo to appease the gods that govern the interplay of laziness and GC. There are comparatively few people who really know how to optimise Haskell code from top to bottom—in part because there is such a distance between top and bottom.


"It’ll be interesting to see how the performance issues play out, no?"

Not really. There's no question whatsoever that GHC can run a fine Wolf3D on fractions of a modern hardware setup. You could do it in pure Python with no NumPy. There's tools to help with the laziness stuff and a 3D rendering loop will fit those perfectly.


Sure, Wolf3D is almost a quarter of a century old by now.

But the performance limits of immutable structures for simulation and graphics are certainly interesting to me.


Absolutely, but it is certainly possible.


>It’ll be interesting to see how the performance issues play out, no?

Not really, 3d rendering in haskell via opengl is not new or interesting at this point. Frag is 8 years old for example: http://www.haskell.org/haskellwiki/Frag


Modern OpenGL exploits immutable data for parallelism all over the place. It also lets (and expects!) you to upload model data (vertices, colors, texture-coords, etc) to the GPU, so you only need to re-upload things that have changed.

You can even stream textures asynchronously using PBOs (pixel buffer objects), and use dual PBOs like double buffers (or using copy-on-write techniques to only re-upload dirty rectangles...)


He's alluding to frame buffers.


Do a lot of other objects read the "front" frame buffer besides the video output?


I think the whole point of a "front" framebuffer is that its only purpose is to be written to the screen. You're only ever writing to the back buffer, which is then flipped, at which point you're writing to a new buffer and it's the next frame.

[edit: If I'm wrong... ouch. But it's been a while.]


@obviouslygreen that is why "all of the objects just referenced a read only version of the world state" doesn't make sense to me as a frame buffer analogy...


It sounds like he's talking about double-buffering "model" data - like an array of all actors and their positions. You can't have one thread reading the data while another writes to it, but you can have the reading thread work on an "old" copy of the data while the writing thread modifies the live data.

Games often want physics/model threads run with a consistent timestep, but have the rendering thread run as fast as possible.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: