Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Оптимизационные забавы...

563
07 октября 2008 года
MrLinker
249 / / 17.09.2006
Вот две мои реализации алгоритма обесцвечивания:
 
Код:
for(UINT i = 0; i<size; i++)
{
    tmp = pix;
    avr = (*pix+++*pix+++*pix++)/3;
           
    *pix_out++ = clipvalue_8(avr+(*tmp++-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(*tmp++-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(*tmp++-avr)*lvl);
[COLOR="Red"]// Вариант исправлен внизу топика[/COLOR]
}

 
Код:
for(UINT i = 0; i<size; i++)
{
    R = *pix++, G = *pix++, B = *pix++;
    avr = (R+G+B)/3;
           
    *pix_out++ = clipvalue_8(avr+(R-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(G-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(B-avr)*lvl);
}

Соответственно:
 
Код:
BYTE *pix, *pix_out, *tmp, R, G, B;
WORD avr;

Время выполнения десяти циклов первой реализации для некоторого изображения: 0.46 сек
Второй: 0.76 сек
Чем объясняется такой выигрыш в скорости первого варианта?

Видно, что во втором варианте на два оператора присваивания больше, но и на три инкримента меньше.
353
08 октября 2008 года
Nixus
840 / / 04.01.2007
Вообще листинг рулит. :-)
Грубо говоря. Первый код проще оптимизировать. Там все возможные переменные можно поместить в доступные регистры общего назначения. Во втором случае переменных гораздо больше.
240
08 октября 2008 года
aks
2.5K / / 14.07.2006
Кстати первый код некоректный. )
563
08 октября 2008 года
MrLinker
249 / / 17.09.2006
 
Код:
Кстати первый код некоректный. )

Так колись :)
240
08 октября 2008 года
aks
2.5K / / 14.07.2006
Некорректно изменять значение *pix более одного раза в данном выражении, насколько я помню. )
563
08 октября 2008 года
MrLinker
249 / / 17.09.2006
В данном выражении порядок и последовательность инкримента не имеет значения.
А вот в более сложных выражениях это может стать проблемой.
Если речь об этом...
240
08 октября 2008 года
aks
2.5K / / 14.07.2006
Нет, речь о том, что оператор разыменования насколько я помню не разделяет точки следования. Как и все остальные в данном выражении. А значит нет никакой гарантии, что изминения произведенные над *pix первый раз, уже сохранились по своему адресу, прежде чем *pix начал меняться еще раз. Тоесть по сути получаем undefined behavior. Тоесть результат в разных ситуациях и на разных компиляторах может быть непредсказуем.

Поправте меня, если я ошибаюсь.
563
08 октября 2008 года
MrLinker
249 / / 17.09.2006
Уловил...
Спасибо.
Возражений нет :)

А жаль.... ;(
563
08 октября 2008 года
MrLinker
249 / / 17.09.2006
Тогда такой вариант:
 
Код:
for(UINT i = 0; i<size; i++)
{
    avr = (*pix+*(pix+1)+*(pix+2))/3;
           
    *pix_out++ = clipvalue_8(avr+(*pix++-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(*pix++-avr)*lvl);
    *pix_out++ = clipvalue_8(avr+(*pix++-avr)*lvl);
}


В скорости не уступает.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог