Handmade Hero»Episode Guide
Optimizing Multithreaded Simulation Regions
?
?

Keyboard Navigation

Global Keys

[, < / ], > Jump to previous / next episode
W, K, P / S, J, N Jump to previous / next marker
t / T Toggle theatre / SUPERtheatre mode
V Revert filter to original state Y Select link (requires manual Ctrl-c)

Menu toggling

q Quotes r References f Filter y Link c Credits

In-Menu Movement

a
w
s
d
h j k l


Quotes and References Menus

Enter Jump to timecode

Quotes, References and Credits Menus

o Open URL (in new tab)

Filter Menu

x, Space Toggle category and focus next
X, ShiftSpace Toggle category and focus previous
v Invert topics / media as per focus

Filter and Link Menus

z Toggle filter / linking mode

Credits Menu

Enter Open URL (in new tab)
0:35A few words on the new format
0:35A few words on the new format
0:35A few words on the new format
1:41Recap and set the stage for the day
1:41Recap and set the stage for the day
1:41Recap and set the stage for the day
2:43Run the game, consult the profiler and assess our current situation
2:43Run the game, consult the profiler and assess our current situation
2:43Run the game, consult the profiler and assess our current situation
9:32handmade_entity.cpp: Stop profiling the entity system, run the game and consult the event count
9:32handmade_entity.cpp: Stop profiling the entity system, run the game and consult the event count
9:32handmade_entity.cpp: Stop profiling the entity system, run the game and consult the event count
11:48handmade_world.cpp: Stop profiling GetWorldChunkInternal(), run the game and consult the profiler
11:48handmade_world.cpp: Stop profiling GetWorldChunkInternal(), run the game and consult the profiler
11:48handmade_world.cpp: Stop profiling GetWorldChunkInternal(), run the game and consult the profiler
13:22handmade_world_mode.cpp: Make PlayWorld() set the WorldChunkDimInMeters larger, run the game and consider drawing the bounds of those chunks
13:22handmade_world_mode.cpp: Make PlayWorld() set the WorldChunkDimInMeters larger, run the game and consider drawing the bounds of those chunks
13:22handmade_world_mode.cpp: Make PlayWorld() set the WorldChunkDimInMeters larger, run the game and consider drawing the bounds of those chunks
16:46handmade_world.cpp: Introduce GetWorldChunkBounds()
16:46handmade_world.cpp: Introduce GetWorldChunkBounds()
16:46handmade_world.cpp: Introduce GetWorldChunkBounds()
21:25handmade_world_mode.cpp: Make UpdateAndRenderWorld() call GetWorldChunkBounds() and draw them
21:25handmade_world_mode.cpp: Make UpdateAndRenderWorld() call GetWorldChunkBounds() and draw them
21:25handmade_world_mode.cpp: Make UpdateAndRenderWorld() call GetWorldChunkBounds() and draw them
23:22Run the game and view that debug visualisation for the chunk
23:22Run the game and view that debug visualisation for the chunk
23:22Run the game and view that debug visualisation for the chunk
26:52handmade_world_mode.cpp: Make PlayWorld() set the chunk size roughly equal to the room size, run the game and view the visualisation
26:52handmade_world_mode.cpp: Make PlayWorld() set the chunk size roughly equal to the room size, run the game and view the visualisation
26:52handmade_world_mode.cpp: Make PlayWorld() set the chunk size roughly equal to the room size, run the game and view the visualisation
29:31handmade_sim_region.cpp: Change BeginWorldChange() to only simulate one room's worth
29:31handmade_sim_region.cpp: Change BeginWorldChange() to only simulate one room's worth
29:31handmade_sim_region.cpp: Change BeginWorldChange() to only simulate one room's worth
31:20Run the game and note how our simulation region erroneously splits entities
31:20Run the game and note how our simulation region erroneously splits entities
31:20Run the game and note how our simulation region erroneously splits entities
32:29handmade_world_mode.cpp: Make UpdateAndRenderWorld() operate on the eight rooms above, below and around the player
32:29handmade_world_mode.cpp: Make UpdateAndRenderWorld() operate on the eight rooms above, below and around the player
32:29handmade_world_mode.cpp: Make UpdateAndRenderWorld() operate on the eight rooms above, below and around the player
36:33Run the game to take a look at how that's working
36:33Run the game to take a look at how that's working
36:33Run the game to take a look at how that's working
38:46handmade_platform.h: Add BeginTicketMutex() to the profiler, run the game to consult the profiler and consider how to improve the multithreading
38:46handmade_platform.h: Add BeginTicketMutex() to the profiler, run the game to consult the profiler and consider how to improve the multithreading
38:46handmade_platform.h: Add BeginTicketMutex() to the profiler, run the game to consult the profiler and consider how to improve the multithreading
42:11handmade_sim_region.cpp: Enable BeginWorldChange() to do a bunch of work without needing to be in a mutex
42:11handmade_sim_region.cpp: Enable BeginWorldChange() to do a bunch of work without needing to be in a mutex
42:11handmade_sim_region.cpp: Enable BeginWorldChange() to do a bunch of work without needing to be in a mutex
46:17handmade_world.cpp: Enable AddToFreeList() to insert the whole list in one go
46:17handmade_world.cpp: Enable AddToFreeList() to insert the whole list in one go
46:17handmade_world.cpp: Enable AddToFreeList() to insert the whole list in one go
48:05Run the game and consult the profiler
48:05Run the game and consult the profiler
48:05Run the game and consult the profiler
50:27handmade_world.cpp: Make RemoveWorldChunk() and AddToFreeList() themselves begin and end the mutex
50:27handmade_world.cpp: Make RemoveWorldChunk() and AddToFreeList() themselves begin and end the mutex
50:27handmade_world.cpp: Make RemoveWorldChunk() and AddToFreeList() themselves begin and end the mutex
52:54handmade_world.cpp: Consider what UseChunkSpace() does, make it begin and end a mutex, run the game and consult the profiler
52:54handmade_world.cpp: Consider what UseChunkSpace() does, make it begin and end a mutex, run the game and consult the profiler
52:54handmade_world.cpp: Consider what UseChunkSpace() does, make it begin and end a mutex, run the game and consult the profiler
56:22handmade_sim_region.cpp: Consider how to improve the ticket-taking in BeginWorldChange()
56:22handmade_sim_region.cpp: Consider how to improve the ticket-taking in BeginWorldChange()
56:22handmade_sim_region.cpp: Consider how to improve the ticket-taking in BeginWorldChange()
59:38Run the game and consult the profiler until we hit a deadlock and investigate why
59:38Run the game and consult the profiler until we hit a deadlock and investigate why
59:38Run the game and consult the profiler until we hit a deadlock and investigate why
1:02:43handmade_world.cpp: Make the correct version of UseChunkSpace() begin and end a mutex, run the game and consult the profiler again
1:02:43handmade_world.cpp: Make the correct version of UseChunkSpace() begin and end a mutex, run the game and consult the profiler again
1:02:43handmade_world.cpp: Make the correct version of UseChunkSpace() begin and end a mutex, run the game and consult the profiler again
1:04:40handmade_world.cpp: Add RemoveWorldChunk() and AddToFreeList() to the profiler, run the game and consult it
1:04:40handmade_world.cpp: Add RemoveWorldChunk() and AddToFreeList() to the profiler, run the game and consult it
1:04:40handmade_world.cpp: Add RemoveWorldChunk() and AddToFreeList() to the profiler, run the game and consult it
1:06:00handmade_sim_region.cpp: Add more timing blocks and functions to the profiler, running the game and consulting that profiler
1:06:00handmade_sim_region.cpp: Add more timing blocks and functions to the profiler, running the game and consulting that profiler
1:06:00handmade_sim_region.cpp: Add more timing blocks and functions to the profiler, running the game and consulting that profiler
1:10:04handmade_sim_region.cpp: Establish that the PushStruct() call in BeginWorldChange() is taking half our time
1:10:04handmade_sim_region.cpp: Establish that the PushStruct() call in BeginWorldChange() is taking half our time
1:10:04handmade_sim_region.cpp: Establish that the PushStruct() call in BeginWorldChange() is taking half our time
1:10:37Note that the timer totally failed
1:10:37Note that the timer totally failed
1:10:37Note that the timer totally failed
1:11:09handmade_memory.h: Investigate why that PushStruct() is so expensive
1:11:09handmade_memory.h: Investigate why that PushStruct() is so expensive
1:11:09handmade_memory.h: Investigate why that PushStruct() is so expensive
1:13:11handmade_sim_region.cpp: Add a timing block around that PushStruct() call in BeginWorldChange(), run the game and inspect the profiler
1:13:11handmade_sim_region.cpp: Add a timing block around that PushStruct() call in BeginWorldChange(), run the game and inspect the profiler
1:13:11handmade_sim_region.cpp: Add a timing block around that PushStruct() call in BeginWorldChange(), run the game and inspect the profiler
1:14:11Consider why we are clearing this buffer
1:14:11Consider why we are clearing this buffer
1:14:11Consider why we are clearing this buffer
1:16:20Break
1:16:20Break
1:16:20Break
1:21:35Return and wonder if the chat figured out what's wrong with the code
1:21:35Return and wonder if the chat figured out what's wrong with the code
1:21:35Return and wonder if the chat figured out what's wrong with the code
1:23:30handmade_sim_region.cpp: Make BeginWorldChange() pass NoClear to that PushStruct() call and run the game to consult the profiler
1:23:30handmade_sim_region.cpp: Make BeginWorldChange() pass NoClear to that PushStruct() call and run the game to consult the profiler
1:23:30handmade_sim_region.cpp: Make BeginWorldChange() pass NoClear to that PushStruct() call and run the game to consult the profiler
1:25:11handmade_sim_region.cpp: Time the ZeroStruct() call, run the game to consult the profiler and consider how to optimise this routine
1:25:11handmade_sim_region.cpp: Time the ZeroStruct() call, run the game to consult the profiler and consider how to optimise this routine
1:25:11handmade_sim_region.cpp: Time the ZeroStruct() call, run the game to consult the profiler and consider how to optimise this routine
1:28:27handmade_debug_ui.cpp: Enable DrawTopClocksList() to print out the cycles per invocation
1:28:27handmade_debug_ui.cpp: Enable DrawTopClocksList() to print out the cycles per invocation
1:28:27handmade_debug_ui.cpp: Enable DrawTopClocksList() to print out the cycles per invocation
1:29:58handmade_math.h: Introduce a 64-bit version of SafeRatio0()
1:29:58handmade_math.h: Introduce a 64-bit version of SafeRatio0()
1:29:58handmade_math.h: Introduce a 64-bit version of SafeRatio0()
1:30:24Run the game and consult the profiler
1:30:24Run the game and consult the profiler
1:30:24Run the game and consult the profiler
1:31:12Break into the ZeroStruct() call in BeginWorldChange() and determine that the clear is costing 7 cycles per byte
1:31:12Break into the ZeroStruct() call in BeginWorldChange() and determine that the clear is costing 7 cycles per byte
1:31:12Break into the ZeroStruct() call in BeginWorldChange() and determine that the clear is costing 7 cycles per byte
1:33:55handmade_sim_region.cpp: Verify that the clear's cycle-time is reasonable
1:33:55handmade_sim_region.cpp: Verify that the clear's cycle-time is reasonable
1:33:55handmade_sim_region.cpp: Verify that the clear's cycle-time is reasonable
1:37:21Consider ways to minimise the memory footprint
1:37:21Consider ways to minimise the memory footprint
1:37:21Consider ways to minimise the memory footprint
1:40:55handmade_sim_region.h: Add EntityHashOccupancy and BrainHashOccupancy to the sim_region struct in order to enable doing the clear with a bitfield
1:40:55handmade_sim_region.h: Add EntityHashOccupancy and BrainHashOccupancy to the sim_region struct in order to enable doing the clear with a bitfield
1:40:55handmade_sim_region.h: Add EntityHashOccupancy and BrainHashOccupancy to the sim_region struct in order to enable doing the clear with a bitfield
1:44:03handmade_sim_region.cpp: Introduce MarkOccupied(), MarkBit() and IsEmpty()
1:44:03handmade_sim_region.cpp: Introduce MarkOccupied(), MarkBit() and IsEmpty()
1:44:03handmade_sim_region.cpp: Introduce MarkOccupied(), MarkBit() and IsEmpty()
1:49:03Run the game, hit the assert in AddEntityToHash(), and fix that assertion to handle the new scheme
1:49:03Run the game, hit the assert in AddEntityToHash(), and fix that assertion to handle the new scheme
1:49:03Run the game, hit the assert in AddEntityToHash(), and fix that assertion to handle the new scheme
1:51:12handmade_sim_region.cpp: Fix the sense of IsEmpty(), run the game and crash in ExecuteBrain()
1:51:12handmade_sim_region.cpp: Fix the sense of IsEmpty(), run the game and crash in ExecuteBrain()
1:51:12handmade_sim_region.cpp: Fix the sense of IsEmpty(), run the game and crash in ExecuteBrain()
1:52:02Build and run in -Od and investigate what's happening
1:52:02Build and run in -Od and investigate what's happening
1:52:02Build and run in -Od and investigate what's happening
1:54:18handmade_sim_region.cpp: Add an assert in AddEntityToHash() to validate the hash, run the game and do not hit that assertion
1:54:18handmade_sim_region.cpp: Add an assert in AddEntityToHash() to validate the hash, run the game and do not hit that assertion
1:54:18handmade_sim_region.cpp: Add an assert in AddEntityToHash() to validate the hash, run the game and do not hit that assertion
1:55:07Step through AddEntityToHash() and investigate what's happening
1:55:07Step through AddEntityToHash() and investigate what's happening
1:55:07Step through AddEntityToHash() and investigate what's happening
1:56:30handmade_sim_region.cpp: Walk through GetOrAddBrain()
1:56:30handmade_sim_region.cpp: Walk through GetOrAddBrain()
1:56:30handmade_sim_region.cpp: Walk through GetOrAddBrain()
1:57:38handmade_sim_region.cpp: Make GetOrAddBrain() set the Hash->ID, run the game and crash in FreeFrame()
1:57:38handmade_sim_region.cpp: Make GetOrAddBrain() set the Hash->ID, run the game and crash in FreeFrame()
1:57:38handmade_sim_region.cpp: Make GetOrAddBrain() set the Hash->ID, run the game and crash in FreeFrame()
1:58:31handmade_sim_region.h: Remove the ID from the entity_hash and brain_hash and instead use their Ptr to identify them
1:58:31handmade_sim_region.h: Remove the ID from the entity_hash and brain_hash and instead use their Ptr to identify them
1:58:31handmade_sim_region.h: Remove the ID from the entity_hash and brain_hash and instead use their Ptr to identify them
1:59:36Run the game and note that "our brains are still not working properly"α
1:59:36Run the game and note that "our brains are still not working properly"α
1:59:36Run the game and note that "our brains are still not working properly"α
2:03:55handmade_sim_region.cpp: Add assertions to GetOrAddBrain() in order to verify ID resolution
2:03:55handmade_sim_region.cpp: Add assertions to GetOrAddBrain() in order to verify ID resolution
2:03:55handmade_sim_region.cpp: Add assertions to GetOrAddBrain() in order to verify ID resolution
2:06:51handmade_sim_region.cpp: Make BeginWorldChange() and GetOrAddBrain() clear the Brains, run the game and note that we're still getting weird behaviour
2:06:51handmade_sim_region.cpp: Make BeginWorldChange() and GetOrAddBrain() clear the Brains, run the game and note that we're still getting weird behaviour
2:06:51handmade_sim_region.cpp: Make BeginWorldChange() and GetOrAddBrain() clear the Brains, run the game and note that we're still getting weird behaviour
2:08:06handmade_memory.h: Enable overflow checking in PushSize_(), run the game and...
2:08:06handmade_memory.h: Enable overflow checking in PushSize_(), run the game and...
2:08:06handmade_memory.h: Enable overflow checking in PushSize_(), run the game and...
2:08:41"So we don't seem to be having any overflow problems at the moment... *stream crashes*"β
2:08:41"So we don't seem to be having any overflow problems at the moment... *stream crashes*"β
2:08:41"So we don't seem to be having any overflow problems at the moment... *stream crashes*"β
2:09:43Wait for Windows to decide to suspend the process
2:09:43Wait for Windows to decide to suspend the process
2:09:43Wait for Windows to decide to suspend the process
2:13:23Run the game normally having removed that overflow checking, and watch the memory counter
2:13:23Run the game normally having removed that overflow checking, and watch the memory counter
2:13:23Run the game normally having removed that overflow checking, and watch the memory counter
2:14:30handmade_sim_region.cpp: Make BeginWorldChange() clear the SimRegion, run the game and watch the profiler
2:14:30handmade_sim_region.cpp: Make BeginWorldChange() clear the SimRegion, run the game and watch the profiler
2:14:30handmade_sim_region.cpp: Make BeginWorldChange() clear the SimRegion, run the game and watch the profiler
2:15:40handmade_sim_region.cpp: Temporarily make BeginWorldChange() clear the EntityHash and BrainHash, run the game and watch the profiler
2:15:40handmade_sim_region.cpp: Temporarily make BeginWorldChange() clear the EntityHash and BrainHash, run the game and watch the profiler
2:15:40handmade_sim_region.cpp: Temporarily make BeginWorldChange() clear the EntityHash and BrainHash, run the game and watch the profiler
2:17:39handmade_sim_region.cpp: Make GetHashFromID() clear upon encountering an empty Entry for now
2:17:39handmade_sim_region.cpp: Make GetHashFromID() clear upon encountering an empty Entry for now
2:17:39handmade_sim_region.cpp: Make GetHashFromID() clear upon encountering an empty Entry for now
2:18:42Run the game successfully and consult the profiler
2:18:42Run the game successfully and consult the profiler
2:18:42Run the game successfully and consult the profiler
2:19:52Q&A
🗩
2:19:52Q&A
🗩
2:19:52Q&A
🗩
2:20:17AsafGartner The stream is down
🗪
2:20:17AsafGartner The stream is down
🗪
2:20:17AsafGartner The stream is down
🗪
2:22:51AsafGartner Did you fix the bug?
🗪
2:22:51AsafGartner Did you fix the bug?
🗪
2:22:51AsafGartner Did you fix the bug?
🗪
2:23:45AsafGartner There's a TODO in ZeroSize. Not sure if you noticed it
🗪
2:23:45AsafGartner There's a TODO in ZeroSize. Not sure if you noticed it
🗪
2:23:45AsafGartner There's a TODO in ZeroSize. Not sure if you noticed it
🗪
2:24:07handmade_memory.h: Remove the TODO from ZeroSize()
2:24:07handmade_memory.h: Remove the TODO from ZeroSize()
2:24:07handmade_memory.h: Remove the TODO from ZeroSize()
2:24:23uplinkcoder What was the bug?
🗪
2:24:23uplinkcoder What was the bug?
🗪
2:24:23uplinkcoder What was the bug?
🗪
2:25:26longboolean We should have something built into the build script that won't let you compile if the stream has gone down. Is this possible to do in a batch script?
🗪
2:25:26longboolean We should have something built into the build script that won't let you compile if the stream has gone down. Is this possible to do in a batch script?
🗪
2:25:26longboolean We should have something built into the build script that won't let you compile if the stream has gone down. Is this possible to do in a batch script?
🗪
2:27:17Update the TODO list
2:27:17Update the TODO list
2:27:17Update the TODO list
2:28:01mtsmox Is it an option to never clear to zero for arenas, and maybe only clear when resetting temporary memory?
🗪
2:28:01mtsmox Is it an option to never clear to zero for arenas, and maybe only clear when resetting temporary memory?
🗪
2:28:01mtsmox Is it an option to never clear to zero for arenas, and maybe only clear when resetting temporary memory?
🗪
2:30:30ctray.cpp: Investigate why the overlay disappeared
2:30:30ctray.cpp: Investigate why the overlay disappeared
2:30:30ctray.cpp: Investigate why the overlay disappeared
2:33:17AsafGartner Is there a still a benefit to using the sim region? Since chunks are room-sized, and simulation is room-based, why not use the chunks directly?
🗪
2:33:17AsafGartner Is there a still a benefit to using the sim region? Since chunks are room-sized, and simulation is room-based, why not use the chunks directly?
🗪
2:33:17AsafGartner Is there a still a benefit to using the sim region? Since chunks are room-sized, and simulation is room-based, why not use the chunks directly?
🗪
2:35:52Wrap it up
🗩
2:35:52Wrap it up
🗩
2:35:52Wrap it up
🗩
2:36:33Anticipate HandmadeCon 2016
🗩
2:36:33Anticipate HandmadeCon 2016
🗩
2:36:33Anticipate HandmadeCon 2016
🗩