выделение памяти для потока в цикле parallel_for - PullRequest
2 голосов
/ 11 февраля 2012

У меня изначально есть однопоточный цикл, который перебирает все пиксели изображения и может выполнять различные операции с данными.

Используемая мной библиотека диктует, что извлечение пикселей из изображения должно выполняться по одной строке за раз. С этой целью I malloc блок памяти, который может содержать одну строку пикселей (BMM_Color_fl - это структура, содержащая RGBA-данные одного пикселя в виде четырех значений с плавающей запятой, а GetLinearPixels() копирует одну строку пикселей из растрового изображения в BMM_Color_fl массив.)

BMM_Color_fl* line = (BMM_Color_fl*)malloc(width * sizeof(BMM_Color_fl));
for (int y = 0; y < height, y++)
{   
    bmp->GetLinearPixels(0, y, width, line); //Copy data of row Y from bitmap into line.
    BMM_Color_fl* pixel = line; //Get first pixel of line.
    for (int x = 0; x < width; x++, pixel++) // For each pixel in the row...
    {
        //Do stuff with a pixel.
    }
}
free(line);

Пока все хорошо!

Ради сокращения времени выполнения этого цикла я написал параллельную версию, используя parallel_for, которая выглядит следующим образом:

parallel_for(0, height, [&](int y)
{   
    BMM_Color_fl* line = (BMM_Color_fl*)malloc(width * sizeof(BMM_Color_fl));
    bmp->GetLinearPixels(0, y, width, line);
    BMM_Color_fl* pixel = line;
    for (int x = 0; x < width; x++, pixel++)
    {
        //Do stuff with a pixel.
    }
    free(line);
});

Несмотря на то, что многопоточный цикл уже быстрее исходного, я понимаю, что все потоки не могут использовать один и тот же блок памяти, поэтому в настоящее время я выделяю и освобождаю память на каждой итерации цикла, что, очевидно, расточительно, так как никогда не будь больше потоков, чем итерации цикла.

У меня вопрос: если и как я могу иметь каждый поток malloc ровно по одному строчному буферу и использовать его повторно (и в идеале освободить его в конце)?

  • В качестве отказа от ответственности я должен заявить, что я новичок в C ++.

Реализация предлагаемых решений:

Concurrency::combinable<std::vector<BMM_Color_fl>> line;

parallel_for(0, height, [&] (int y)
{
    std::vector<BMM_Color_fl> lineL = line.local();
    if (lineL.capacity() < width) lineL.reserve(width);

    bmp->GetLinearPixels(0, y, width, &lineL[0]);

    for (int x = 0; x < width; x++)
    {
         BMM_Color_fl* pixel = &lineL[x];
         //Do stuff with a pixel.
    }       
});

Как и предполагалось, я консервировал malloc и заменил его на vector + reserve.

Ответы [ 2 ]

0 голосов
/ 11 февраля 2012

Вы можете использовать Concurrency::combinable класс для достижения этой цели.Мне лень публиковать код, но я уверен, что это возможно.

0 голосов
/ 11 февраля 2012

Вместо того, чтобы каждый поток вызывал функцию parallel_for (), они должны вызывать другую функцию, которая распределяет память, вызывает функцию parallel_for (), а затем освобождает память.

...