Developing Avoyd, a Voxel Editor able to handle large models and a six degrees of freedom movement Game with editable terrain.
Doug Binks - 05 Sep 2015
This is the second in a series of articles detailing the inner workings and evolution of the permissively open source multithreading task scheduler enkiTS for C and C++ (including C++ 11). In the first article of this series I covered the external interfaces and their implementation. This post will cover the task threading function, running tasks, and waiting for tasks.
Figure 1: Screenshot of Avoyd being profiled with microprofile and ImGui integration available in enkiTSExamples. Solid bars above named tasks show when threads are active - the wait functionality allows the core to idle or other threads to run.
Doug Binks - 22 Aug 2015 - edited 28 Jun 2019
This is the first in a series of articles detailing the inner workings and evolution of the permissively open source multithreading task scheduler enkiTS for C and C++ (including C++ 11). The interface has evolved somewhat since this article, and whilst I've made minor changes to update it, keeping it fully up to date is difficult, so please check out the full code on github.
enkiTS - Code and basic examples for the task scheduler described this article.
enkiTSExamples - Further enkiTS examples adding profiling instrumentation.
If you're writing a compute intensive programming task on consumer hardware, and you want to use as much of the systems resources as possible, then you'll need to consider multithreading on the CPU. There are a number of ways to approach this, but the current gold standard approach for developers who want both simplicity and control is a task scheduler which can handle data-parallelism (in the games industry a task is often referred to as a job). Task parallelism allows you to run different types of computation at the same time, whilst data-parallelism enables you to run the same computation over a set of data across different threads at the same time. Note that I won't consider Single Instruction Multiple Data (SIMD) parallelism here, but if you're doing computations you probably should. Additionally, I won't cover multithreading methods for handling large latency, such as waiting on hard disk or socket transactions.
enkiTS in our game, Avoyd, being profiled using the microprofile and Dear ImGui integration available in enkiTSExamples. This is an old image of the game and the current codebase uses newer enkiTS API features such as priorities and pinned tasks making for a much more complex task graph.
Juliette Foucaut - 29 Jun 2015
At the end of May, a month ago today, we attended Feral Vector. We saw many projects and met lots of interesting people. Although we hadn’t planned on it, we ended up showing Avoyd for the first time. In light of the nice feedback we got, we think that releasing it sooner, even without gameplay, would probably be a good idea.
Doug Binks - 31 Jan 2015
As usual, whilst working on one aspect of Avoyd I hit a hurdle and decided to take a break by tweaking some visuals - specifically looking at the normals for my surfaces. I added a step to generate face normals in the pixel shader using the derivatives of world space position [see: Normals without normals by Angelo Pesce and the Volumes of Fun wiki on Computing Normals], and immediately noticed precision issues when close to the surface. I'll demonstrate the issue and my quick fix which uses eye relative position instead of world space, before explaining what's happening in full.
Figure 1: The image on the left shows the face normals calculated in the pixel shader using the world space position, and on the right we take the eye relative world space position.