У меня изначально есть однопоточный цикл, который перебирает все пиксели изображения и может выполнять различные операции с данными.
Используемая мной библиотека диктует, что извлечение пикселей из изображения должно выполняться по одной строке за раз. С этой целью 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
.