0
\$\begingroup\$

I'm building a game from scratch using OpenTK, in C#. It is in its base form a mesh-based voxel engine. I have a decent startup on the chunk building algorithm, multiple blocks, block data, etc, but now I am thinking of multithreading the chunk building algorithm. I understand that multithreading is not a band-aid to poorly optimized code, but I feel as though while I could spend time on optimizing, I could start multithreading the chunk building algorithm (which is probably going to happen either way), and optimize the algorithm itself later. The only issue I have is with the Thread class, and how it appears to work in my code.

In my code, I have a class called Chunk that handles the chunk data, position, mesh building, and save/load methods. Right now, the main contructor of Chunk looks like this:

public Chunk(int x, int y, int z)
{

    Stopwatch elapsed = Stopwatch.StartNew(); // debug info on how fast it takes to gen
    cx = x; // chunk X
    cy = y; // chunk Y
    cz = z; // chunk Z

    // what I want to multithread
    // this thread appears to run as it is on the main thread for some reason.
    Thread thread = new Thread(() => {

        Console.WriteLine(Thread.CurrentThread.Name);
        IsReady = false;
        GenerateNoiseValues(12345); // noise pregen
        GenerateBlockData(); // block data generation
        GenerateChunkMesh(); // mesh gen from block data
        IsReady = true;

    });
    thread.Name = "hi";
    thread.Start();
    Console.WriteLine(Thread.CurrentThread.Name);

    // this is to worry about later; data syncing
    vbo = Vbo.Generate(blockvertdata, BufferUsageHint.DynamicDraw);
    vao = Vao.Generate(AttribPointerMode.Chunk);
    Vbo.Unbind();
    Vao.Unbind();

    model = Matrix4.CreateTranslation(x * size, y * size, z * size);
    elapsed.Stop();
    TimeSpan elapsedtime = elapsed.Elapsed;
    Console.WriteLine("Made a chunk in " + elapsedtime.TotalSeconds + " seconds.");

}

In the constructor, I have a Thread to deal with the generation of all the chunk noise, data, and mesh itself. However, when I call thread.Start(), it appears as if the thread is running as if it is on the main thread as well, and not on a separate thread.

Here are some comparisons with time when it is on the Thread vs when it is not:

Time it took to generate chunks with the Thread Time it took to generate chunks with the Thread

Time it took to generate chunks without the Thread Time it took to generate chunks without the Thread

Time it took to generate chunks without any pregen/blockdata gen/meshgen code (the whole block of Thread deleted) enter image description here

As a unfamiliar user with Threading, I feel as though using the Thread would result in the third image, but that is not the case. I am wondering why that is the case, cause that is just how I see using the Thread would do, since it would offload the generation into a separate thread.

If you would like to view the whole Chunk class, I have a pastebin: https://pastebin.com/XP3Ec6n7 If the multitude of making the chunks appear to be the issue, I also have the class for that. It is specifically GenerateChunksWithinRadius() that I am using the generate the 512 chunks: https://pastebin.com/8j3dnPSD

I understand that multithreading is not a light topic, and not a band-aid, but I feel as though the thread.Start() is pretty self explanatory based on what I have read and I don't know why the code getting executed in the thread is as though there is no new thread. I appreciate anyone's help on helping me find what the cause of this is.

\$\endgroup\$
3
  • \$\begingroup\$ To clarify, are you expecting the thread to complete and the chunk to be ready before exiting the constructor? What happens if you leave in all the code except the OpenGL calls? [Not an OpenTK user, but I believe OpenGL expects a single thread to manage resources] How many compute cores available to your process? [side-note: You should be using a thread pool, but that's secondary to working out why you aren't getting parallel execution] \$\endgroup\$
    – Basic
    Apr 10 at 11:43
  • \$\begingroup\$ When I see "in the constructor", I ask who is the chicken and what is the egg. "Most" components have a "Loading" and "Loaded" event that signal various states of readiness. Alternatively, one can create a "builder" that stands "outside" of the object graph, avoiding the issue all together. \$\endgroup\$ Apr 10 at 17:27
  • 1
    \$\begingroup\$ @Basic I want the constructor to be finished, regardless if the chunk is ready or not before exiting the constructor, and the thread appears to finish(?) before exiting the constructor for some reason. If I leave out the OpenGL calls in the constructor, it is the same, and takes around 5 seconds to finish. I don't expect the thread to be complete before the existing the constructor. For the compute cores, I'm not sure what you mean but if you mean how many cores my CPU has, it's 6 of them. \$\endgroup\$
    – Pale_Gray
    Apr 10 at 19:07

0

You must log in to answer this question.

Browse other questions tagged .