Building a load-balanced task scheduler – Part 1: Basics

With multicore hardware becoming the norm in both PC/console-based gaming as well as on mobile platforms, it is crucial to take advantage of every processor core and thread being thrown at us developers. Therefore, it is important to build technology alleviating the task of writing correct, multi-threaded code.

In order to achieve that, this series will try to explain how to build a load-balancing, work-stealing task scheduler.

Continue reading

volatile != thread synchronization

Everybody knows that writing correct multithreaded code is hard, even when using proper synchronization primitives like mutexes, critical sections, and the likes. (Ab)using the volatile keyword for synchronization purposes makes a programmer’s life even harder – read on if you care to know why, and help spreading the word.

Continue reading

Adventures in data-oriented design – Part 1: Mesh data

Let’s face it, performance on modern processors (be it PCs, consoles or mobiles) is mostly governed by memory access patterns. Still, data-oriented design is considered something new and novel, and only slowly creeps into programmers’ brains, and this really needs to change. Having co-workers fix your code and improving its performance really is no excuse for writing crappy code (from a performance point-of-view) in the first place.

Continue reading

SIMD’ifying multi-platform math

Nowadays, with each platform (even mobiles) supporting some sort of SIMD registers and operations, it is crucial for every codebase/engine to fully utilize the underlying SIMD functionality. However, SIMD instruction sets, registers and types vary for each platform, and sometimes between compilers as well.

This blog post explains how a platform-agnostic SIMD implementation can be built, without having to port large portions of the codebase for each new supported platform.

Continue reading

Wiring physical devices to abstract inputs

In an earlier post, we discussed different methods of gathering keyboard input in Windows. Today, we will cover how multi-platform and multi-device input can be handled in a straightforward way, showing a very efficient implementation of the underlying parts.

Continue reading

Generic, type-safe delegates and events in C++

While other languages such as C# offer type-safe callbacks/delegates out-of-the-box, C++ unfortunately does not offer such features. But delegates and events provide a nice way of “coupling” completely unrelated classes without having to write a lot of boilerplate code.

This blog post describes a generic, type-safe implementation of such delegates and events using advanced C++ features such as non-type template arguments and partial template specialization, supporting both free functions and member functions alike, without any restrictions or dynamic memory allocation.

Continue reading

Properly handling keyboard input

Working with Windows, such a seemingly simple task such as handling keyboard input can turn into a small engineering nightmare. There is a myriad of deceitful APIs for basically doing the same thing, yet every single one of them has its own flaws. This post details how this was solved in Molecule – read on for a journey through Windows hell.

Continue reading

File system – Part 1: Platform-specific API design

Typically, a file system in a game engine comes with all the bells and whistles like multiple file devices, support for zipped files, encryption, device aliases, asynchronous I/O, and more. But buried underneath every file system lives a low-level implementation (directly using OS/SDK functions), which in turn is used in the high-level file system.

This low-level implementation should be the only platform-specific file implementation in the whole file system, and is the topic of today’s post.

Continue reading

An improved assert()

assert() is a very useful tool for ensuring that pre- and post-conditions, as well as invariants, are met upon calling or exiting a function. If you have never used assertions before, start using them now – they will help you find bugs in your own code, and quickly highlight when code is not used in the way originally intended.

Still, there are a few bits missing in the standard assert(), which is why we will try to build an improved version of it today.

Continue reading

Memory system – Part 4

In the last few installments of the Memory system series, we were mostly concerned with how ordinary memory allocation using new and delete works internally, and how we can build our own tools to provide additional functionality. One thing we haven’t discussed yet are the memory arenas which are responsible for actually allocating memory, while providing additional things like bounds checking, memory tracking, etc.

Continue reading

Memory system – Part 3

Continuing from where we left off last time, we’re about to optimize our NewArray and DeleteArray function templates for POD-types this time. Let’s start easy by talking about the implementation itself first, and then putting pieces of the puzzle together one by one. Following is the implementation of the function templates NewArrayPOD and DeleteArrayPOD:

Continue reading

Memory system – Part 2

In the last installment of the memory system series, we covered how new, delete, and their variants work. This time, we’re going to build our own little toolset which allows us to create new instances (or arrays of instances) of any type using custom allocator classes in a standards-compliant way. Be prepared for some function templates, type-based dispatching, template magic, and nifty macros.

Continue reading