Первоначально у меня был однопоточный цикл, который выполняет итерацию по всем пикселям изображения и может выполнять различные операции с данными.распределение памяти на поток в цикле parallel_for
Библиотека, которую я использую, диктует, что извлечение пикселей из изображения должно выполняться по одной строке за раз. С этой целью я 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
.
Извините, но я не могу * не жалуюсь: 'malloc' не имеет места в коде C++. Ни при каких обстоятельствах, если вы на самом деле не выполняете собственный распределитель в терминах 'malloc' (но почему бы вы никогда не делали этого, это выходит за рамки меня, поскольку он уже использует этот распределитель по умолчанию). –
@ Konrad Я не спорю, но не могли бы вы объяснить, почему? – Rotem
Поскольку C++ специально инкапсулирует механизм 'malloc' /' free' двумя способами: (1) через 'new' /' delete' и (2) через распределители. Оба обеспечивают превосходный интерфейс из-за сильной типизации. Это улучшает читаемость и позволяет избежать ошибок типа. Кроме того, даже эти методы должны в общем случае (читай: почти * всегда *) избегать в пользу управляемой памяти (в вашем случае, «std :: vector», но более общие умные указатели), чтобы избежать утечек памяти и упростить код (нет явной очистки). –