Очень хочется увидеть фотографии из коридора, чтобы было понятнее, с чем придётся иметь дело. Будет ли он огорожен от прямого солнечного света? Если вдруг лазерное пятно не будет видно на освещённой солнцем панели, или солнце будет освещать половину маркера, то это не очень приятный сюрприз.
Только сначала лучше померить, действительно ли это скомпилируется в более быстрый код. У меня было несколько идей по поводу второго цикла: пробовал производить вычисления вместо обращения к палитре, пробовал считать по 4 байта и писать сразу dword, пробовал разносить чтение и запись на 1024 байта, пробовал вручную разворачивать цикл, в итоге оставил самый простой вариант, как самый быстрый.
int b[L];
палитру лучше было сделать из (unsigned char)
lAB += (int)(valueR * 0.299 + valueG * 0.587 + valueB * 0.114);
при округлении в этом месте будет теряться много информации, например, если весь буфер будет заполнен синим цветом с яркостью 6, то переменная lAB, которая средняя яркость всех пикселей, будет равна 0.
ну и ещё много мелочей, вроде «return 0;» в функции которая возвращает void, кучи лишних приведений типов и ни о чём не говорящих названий переменных.
Основная ошибка автора — использование распараллеливания там, где это не нужно. Вычислений почти нет, обращений к памяти много. Основное время процессор будет ждать передачи дынных, на сколько потоков это не раскидывай — лучше не будет.
Вместо 1.0 максимальная яркость принята за 256, поэтому константы почти такие же как у автора.
77 / 256 ~= 0.3
150 / 256 ~= 0.586
29 / 256 ~= 0.113
По поводу умножения и сдвига на 8 (деления на 256): да, константы для операций с фиксированной точкой могут показаться странными.
Эта статья — отличный пример неправильного использования многопоточности.
Вычислений почти нет, в основном работа с памтятью. Вот код, который на на 15% быстрее и выполняется в одном потоке:
void contrastFilter(unsigned char * imageData, size_t dataSize, int contrast) // contrast (256 - normal)
{
unsigned char buf[256];
unsigned int midBright = 0;
for (size_t i = 0; i < dataSize; i += 3)
midBright += imageData[i] * 77 + imageData[i + 1] * 150 + imageData[i + 2] * 29;
midBright /= (256 * dataSize / 3);
for (size_t i = 0; i < 256; i++)
{
int a = (((i - midBright) * contrast) >> 8) + midBright;
if (a < 0) buf[i] = 0;
else if (a > 255) buf[i] = 255;
else buf[i] = a;
}
for (size_t i = 0; i < dataSize; i++)
imageData[i] = buf[imageData[i]];
}
Давай. А мы посмотрим, как оно заработает на PowerPC
тогда uint64_t
1920 * 1080 * 256 = 0x 1FA4 0000
Размер long int сейчас обычно такой же как и int, возможно, вы имели в виду long long int.
int b[L];
палитру лучше было сделать из (unsigned char)
lAB += (int)(valueR * 0.299 + valueG * 0.587 + valueB * 0.114);
при округлении в этом месте будет теряться много информации, например, если весь буфер будет заполнен синим цветом с яркостью 6, то переменная lAB, которая средняя яркость всех пикселей, будет равна 0.
ну и ещё много мелочей, вроде «return 0;» в функции которая возвращает void, кучи лишних приведений типов и ни о чём не говорящих названий переменных.
(у поста уже 17 плюсов, кто все эти люди? :) )
Вместо 1.0 максимальная яркость принята за 256, поэтому константы почти такие же как у автора.
77 / 256 ~= 0.3
150 / 256 ~= 0.586
29 / 256 ~= 0.113
По поводу умножения и сдвига на 8 (деления на 256): да, константы для операций с фиксированной точкой могут показаться странными.
Вычислений почти нет, в основном работа с памтятью. Вот код, который на на 15% быстрее и выполняется в одном потоке: