Распараллеливание обработки изображений

API dlib.image позволяет создавать фильтры, которые легко распараллеливать на несколько процессоров. Изображение условно разбивается на несколько блоков заданного размера, которые затем обрабатываются фильтром через std.parallelism.

import std.parallelism;
import dlib.functional.range;
import dlib.image.image;

struct Block
{
    uint x1, y1;
    uint x2, y2;
}

alias Range!uint PixRange;

void parallelFilter(
     SuperImage img, 
     void delegate(PixRange blockRow, PixRange blockCol) ffunc, 
     uint bw = 100,
     uint bh = 100)
{
    if (bw > img.width)
        bw = img.width;
    if (bh > img.height)
        bh = img.height;

    uint numBlocksX = img.width / bw + ((img.width % bw) > 0);
    uint numBlocksY = img.height / bh + ((img.height % bh) > 0);

    Block[] blocks = new Block[numBlocksX * numBlocksY];
    foreach(x; 0..numBlocksX)
    foreach(y; 0..numBlocksY)
    {
        uint bx = x * bw;
        uint by = y * bh;

        uint bw1 = bw;
        uint bh1 = bh;

        if ((img.width - bx) < bw)
            bw1 = img.width - bx;
        if ((img.height - by) < bh)
            bh1 = img.height - by;

        blocks[y * numBlocksX + x] = Block(bx, by, bx + bw1, by + bh1);
    }

    foreach(i, ref b; taskPool.parallel(blocks))
    {
        ffunc(range!uint(b.x1, b.x2),
              range!uint(b.y1, b.y2));
    }
}

Пример (закрашивание сплошным цветом):

SuperImage filterTestMultithreaded(SuperImage img)
{
    auto res = img.dup;
    
    img.parallelFilter((PixRange row, PixRange col)
    {
        foreach(x; row)
        foreach(y; col)
        {
            res[x, y] = hsv(180.0f, 1.0f, 0.5f);
        }
    });
    
    return res;
}

Для сравнения – однопоточный вариант:

SuperImage filterTestSinglethreaded(SuperImage img)
{
    auto res = img.dup;
    
    foreach(x; img.row)
    foreach(y; img.col)
    {
        res[x, y] = hsv(180.0f, 1.0f, 0.5f);
    }
   
    return res;
}

На двухъядерном Intel Dual Core T2390 (1.86 ГГц) многопоточный вариант показывает прирост производительности на 70%.