Есть устоявшееся мнение, дескать обработка (изображений) в целых (16-битных) числах - это быстро, а делать то же самое в плавучке - медленно.
А я вот тут читаю ассемблер, порожденный компилятором из C-шного кода обработки изображения. Много думаю.
Имею сказать, что распространенный в настоящее время формат "16-битное целое на компонент" - это максимально неудачный способ с точки зрения эффективности обработки:
- от малейшего чиха переполняется или
превращается в тыкву обнуляется, нужно постоянно следить за диапазоном;
- векторные (SSE,AVX) операции с этим типом - очень ограничены, да и не векторные - тоже.
В результате, сплошные мучения компилятору, а результат - медленно работает. Скажем, вот такой вот код (из dcraw), который делает преобразование по матричному профилю для 3-4 входных каналов (цветов) и трех выходных:
out[0] = out[1] = out[2] = 0;
for (сc=0;сc<colors;сc++) {
out[0] += out_cam[0][сc] * img[сc];
out[1] += out_cam[1][сc] * img[сc];
out[2] += out_cam[2][сc] * img[сc];
}
for(cс=0;сc<3;сc++) img[сc] = CLIP((int) out[cс]);
img[] - unsigned short, out[] - int, out_cam[] - float.
Смотрю на код, который порождает интеловский компилятор. Ну код, да. (три-)четыре load по 2 байта (количество loads зависит от colors /количества цветов/), дальше "вручную" выписанный dot product (нормальный, насколько это возможно), ну и обрезание до диапазона 0-65к и store.
Скорость работы этого кода - 100 мегапикселей в секунду на Sandy Bridge 4.5Ghz (в один поток, понятно что параллелится это на ура). Как-то не очень....
Да, считаем в мегапикселях т.к. в unsigned short у нас 8 байт на (4-компонентный) пиксель, а для float/int - 16 байт.