DinkydauSet / ExploreFractals

A tool for testing the effect of Mandelbrot set Julia morphings
GNU General Public License v3.0
5 stars 1 forks source link

slow bitmap renders during fractal renders #38

Open DinkydauSet opened 2 years ago

DinkydauSet commented 2 years ago

I thought it was a good idea to use a few more threads than cores to be sure that all cores are kept busy, but I have noticed that this makes bitmap renders very slow during fractal renders. If there is 1 idle core left, bitmap renders finish much faster. Unfortunately, using (number of cores - 1) threads means that on a dual core computer, only one core is used, so that's not a good idea. Also, even on a computer with many cores, it's stupid not to use one for rendering if that's all the computer is doing. I don't know a good solution for that.

DinkydauSet commented 2 years ago

Idea: with a threadpool, the bitmap render can be queued. That only works well if the blocks of work assigned to a thread are not too big, otherwise it takes too long for the bitmap render to start. The blocks of work also shouldn't be too small, otherwise the coordinating entity has too much to do. I did some tests with using a mutex for every pixel, which was too slow, but a mutex per 64 pixels (for example) is ok: https://github.com/DinkydauSet/ExploreFractals/issues/34#issuecomment-1014649173

DinkydauSet commented 2 years ago

Probably the solution is this:

Currently I create worker threads for renders like this:

while (created_threads < canvas.number_of_threads)
{
    worker_threads[created_threads++] = thread(&Render::sampling_algorithm_work_loop, this, ref(wd));
}

Doing it this way lowers the priority of the render threads:

while (created_threads < canvas.number_of_threads)
{
    worker_threads[created_threads++] = thread(&Render::sampling_algorithm_work_loop, this, ref(wd));
    HANDLE hThread = worker_threads[created_threads-1].native_handle();
    SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
}

This means that bitmap render threads will have a higher priority than render threads, which appears to solve the problem. Bitmap renders are much faster during renders.

This uses a windows api function so it should be tested if it works in wine.