Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    8
  • comments
    20
  • views
    8176

WIP: Week 3 -- Threading, Chunking, and Optimizations!

Sign in to follow this  
studentTeacher

713 views

Hello all!

This week, I begun work on the threading model for the engine. Since having a thread for each component (rendering, physics, main game loop, input, etc) wasn't feasible and left a lot to be desired for the engine, I changed it to a Fork/Join or Job model. This allows easy use of a thread pool, which is easy and intuitive to use. I created a ThreadPool class that manages the queueing of tasks and the management of threads.

This was new territory to me, since I wanted to play with C++0x features like condition variables, return_type, std::futures/std::forward, etc. I also learned about more than the typical lambda function, and made the ThreadPool class accept any type of method: class method, static methods, functions, lambda expressions, etc. The interface looks like the following, and returns an std::future for the result:[code=:0]ThreadPool::create(std::thread::hardware_concurrency() - 1);// ...//auto = std::futureauto result1 = ThreadPool::enqueue([]{return "test"});//getInt returns 42.//auto = std::futureauto result2 = ThreadPool::enqueue(&getInt);// ..std::cout << "Result 1: " << result1.get() << std::endl;std::cout << "Result 2: " << result2.get() << std::endl;// ...ThreadPool::destroy();
I have the threads sleep on the condition_variable in ThreadPool until there's tasks for them to complete. Each call returns an std::future, from which the result is received.

Once I had the threading model, I started using it! I chunked out the world, and threaded different aspects of it (loading, unloading, generation, etc.). Below is an example of it working:

Screen Shot 2015-01-04 at 10.46.41 AM.png

Lastly, I noticed some issues with my mesh generation. It was taking 125-160ms, and that is WAY too long -- my Java version managed to generate chunk meshes in about 30ms. After a long time looking through the code, unrolling loops, etc., I was able to get it down to a whopping 22-25ms!! Now I can generate chunks (threaded) about 2-4 per frame, rather than one at a time! AND since I've got a Job framework going, I can have mesh generation take most of the frame time, and have the renderer grab the result and render it at the end!

This next week, I hope to start putting together a noise library for creating terrain. Alongside that, I need to start working on transparency (UGH It's already giving me a headache...) in order to handle water, liquids, and translucent materials.

Best,
ST
Sign in to follow this  


2 Comments


Recommended Comments

This is looking good. I use threading exclusively for the chunk generation since generating voxels can be done independently, and the same with mesh generation.

 

I haven't thought about unrolling loops, though. My data is stored in 3D arrays and thus uses loops nested 3 deep for more readable code.

Share this comment


Link to comment

The real issue was when meshing (this time around), I was originally looping through the data 6 times, and I cut that down to 3. I also have found threading useful for some other tools, like sorting transparency and chunk order for rendering. 

 

As for 3D vs. 1D unrolled Arrays, it depends mostly on the compiler I believe. I've found a speedup going unrolled, but on other people's games they've seen a slowdown from the same move.....not too difficult to try out though! ;)

 

For readability, I still loop in 3D, but I access voxels like this:

_ushort getVoxel(int x, int y, int z) {
    // if you want to: assert (x, y, z) in chunk

    return _voxels[index(x, y, z)];
}

Keeps everything readable outside the method :)

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!