Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2008.02.17;
Скачать: [xml.tar.bz2];

Вниз

Смешение цветов, быстрее можно ли?   Найти похожие ветки 

 
DVM ©   (2008-01-14 12:20) [0]

Обратите внимание, что степень смешения должна быть типа Single - так продиктовано задачей где используется смешение.

function MixerColors(FromColor, ToColor: TColor; Rate: Single): TColor;
var
 r1, g1, b1: byte;
 r2, g2, b2: byte;
 r3, g3, b3: byte;
 r: Single;
 ra, rb: byte;
begin
 RA := round(Rate * 255);
 RB := 255 - RA;

 //r1 :=  lo(FromColor);
 g1 :=  lo(FromColor shr 8);
 b1 :=  lo(FromColor shr 16);

 //r2 :=  lo(ToColor);
 g2 :=  lo(ToColor shr 8);
 b2 :=  lo(ToColor shr 16);

 r3 := (Lo(FromColor) * RA + Lo(ToColor) * RB) shr 8;
 g3 := (g1 * RA + g2 * RB) shr 8;
 b3 := (b1 * RA + b2 * RB) shr 8;

 Result := (r3 or (g3 shl 8) or (b3 shl 16));
end;


 
Сергей М. ©   (2008-01-14 12:24) [1]

А в чем, собссно, тормоза ?


 
DVM ©   (2008-01-14 12:27) [2]


> Сергей М. ©   (14.01.08 12:24) [1]

не, тормозов нет, просто спортивный интерес, можно ли еще быстрее даже на ASM?


 
Rouse_ ©   (2008-01-14 12:29) [3]

Сколько вызовов данной функции планируется в секунду?


 
oxffff ©   (2008-01-14 12:31) [4]


> Rouse_ ©   (14.01.08 12:29) [3]


Inline?


 
DVM ©   (2008-01-14 12:32) [5]


> Rouse_ ©   (14.01.08 12:29) [3]

Сложно сказать. Но предполагается ее использовать для антиалиазинга линий и фигур и эффектов полупрозрачности.


 
homm ©   (2008-01-14 12:33) [6]

А чего g1, b1 не подставил в выражение?


 
homm ©   (2008-01-14 12:35) [7]

> [0] DVM ©   (14.01.08 12:20)
> RA := round(Rate * 255);

Вернет 255 для значений от  254,5 до 255, а 254 вернет для значений от 253,5 до 254,5. Не складно.


 
DVM ©   (2008-01-14 12:36) [8]


> А чего g1, b1 не подставил в выражение?

опс, забыл. Подставил. Скорость немноговозросла.


 
Сергей М. ©   (2008-01-14 12:37) [9]


> DVM ©   (14.01.08 12:32) [5]


> предполагается ее использовать для антиалиазинга линий и
> фигур и эффектов полупрозрачности


Значит, вероятно, предполагается, что один и тот же Rate будет использован при вызове ф-ции для всех точек смешиваемых изображений ?

Тогда зачем всякий раз при вызове ф-ции вычислять RA и RB ? Вполне достаточно сделать это всего один раз.


 
Rouse_ ©   (2008-01-14 12:37) [10]

Вот так убрать можно лишние действия:

function MixerColors1(FromColor, ToColor: TColor; Rate: Single): TColor;
var
g1, b1: byte;
g2, b2: byte;
r3, g3, b3: byte;
ra, rb: byte;
begin
RA := round(Rate * 255);
RB := 255 - RA;

g1 :=  FromColor shr 8;
b1 :=  FromColor shr 16;

g2 :=  ToColor shr 8;
b2 :=  ToColor shr 16;

r3 := (Byte(FromColor) * RA + Byte(ToColor) * RB) shr 8;
g3 := (g1 * RA + g2 * RB) shr 8;
b3 := (b1 * RA + b2 * RB) shr 8;

Result := (r3 or (g3 shl 8) or (b3 shl 16));
end;


 
DVM ©   (2008-01-14 12:38) [11]


> Значит, вероятно, предполагается, что один и тот же Rate
> будет использован при вызове ф-ции для всех точек смешиваемых
> изображений ?

Для полупрозрачности - верно, но для краевого антиалиазинга нет - там все точки разные.


 
homm ©   (2008-01-14 12:38) [12]

> [0] DVM ©   (14.01.08 12:20)


А теперь рассмотри вариант, когда Rate = 1.0
RA := round(Rate * 255);
RB := 255 - RA;

RA = 255;
RB = 0;

g3 := (g1 * RA + g2 * RB) shr 8;

g3 := (g1 * 255 + 0) / 256;
g3<>g1, хотя Rate = 1.0


 
DVM ©   (2008-01-14 12:43) [13]


> homm ©   (14.01.08 12:35) [7]

Да, я знаю. На это можно закрыть глаза. Все равно визуально неотличимо.


> Rouse_ ©   (14.01.08 12:37) [10]
> Вот так убрать можно лишние действия:

На скорость не повлияло


 
Сергей М. ©   (2008-01-14 12:43) [14]


> DVM ©   (14.01.08 12:38) [11]


Значит нужны разные алгоритмы для тех или иных задач.
Стремление к универсальности алгоритма никогда еще не приводило к приросту его производительности.


 
homm ©   (2008-01-14 12:44) [15]

> [13] DVM ©   (14.01.08 12:43)
> На это можно закрыть глаза. Все равно визуально неотличимо.

После ста наложений станет вполне отличимо.


 
DVM ©   (2008-01-14 12:44) [16]


> А теперь рассмотри вариант, когда Rate = 1.0

для Rate = 1 будет отдельная добавка, там считать вообще не надо.


 
homm ©   (2008-01-14 12:45) [17]

> [16] DVM ©   (14.01.08 12:44)
> для Rate = 1 будет отдельная добавка, там считать вообще
> не надо.

Блин, ну возьми Rate = 0,999. Результат будет не верен для любого значения, т.к. ты умнеожаешь на 255, а делишь на 256 всегда


 
DVM ©   (2008-01-14 12:46) [18]


> После ста наложений станет вполне отличимо.

Другого ничего в голову не приходит мне что-то.


 
homm ©   (2008-01-14 12:51) [19]

> [18] DVM ©   (14.01.08 12:46)
> Другого ничего в голову не приходит мне что-то.

RA := trunc(Rate * 257);


 
homm ©   (2008-01-14 12:53) [20]

ra, rb: byte;

DWORD


 
oxffff ©   (2008-01-14 12:56) [21]


> homm ©   (14.01.08 12:51) [19]
> > [18] DVM ©   (14.01.08 12:46)
> > Другого ничего в голову не приходит мне что-то.
>
> RA := trunc(Rate * 257);


А если rate=1 ?


 
homm ©   (2008-01-14 12:59) [22]

> [21] oxffff ©   (14.01.08 12:56)
> А если rate=1 ?

Очевидно поправка,
либо через if, либо умножать на 256,999


 
DVM ©   (2008-01-14 13:03) [23]


> homm ©   (14.01.08 12:51) [19]


> homm ©   (14.01.08 12:59) [22]

потеряем в скорости


 
oxffff ©   (2008-01-14 13:05) [24]


> DVM ©   (14.01.08 13:03) [23]


Чего ты хочешь добиться?
Если тебе нужна скорость.
IMHO не изобретай велосипед. См. готовые реализации.
Если тебе нужна скорость, см. в сторону использования GPU,
в том числе и для расчетов.


 
DVM ©   (2008-01-14 13:06) [25]

Пока что самый быстрый вариант таков (если не принимать в расчет недостаток, замеченный homm):

function MixerColors(FromColor, ToColor: TColor; Rate: Single): TColor;
var
 ra, rb: byte;
begin
 RA := round(Rate * 255);
 RB := 255 - RA;
 result := (((Lo(FromColor) * RA + Lo(ToColor) * RB) shr 8) or
           (((Lo(FromColor shr 8) * RA + Lo(ToColor shr 8) * RB) shr 8) shl 8) or
           (((Lo(FromColor shr 16) * RA + Lo(ToColor shr 16) * RB) shr 8) shl 16));
end;


224 микросекунды на 10000 повторов


 
DVM ©   (2008-01-14 13:09) [26]


> oxffff ©   (14.01.08 13:05) [24]


> Чего ты хочешь добиться?
> Если тебе нужна скорость.
> IMHO не изобретай велосипед. См. готовые реализации.

Да я уже добился собственно чего хотел :) Что значит готовые реализации? Аппаратное ускорение? Все реализации, даже на ASM которые мне попались я уже обогнал.


> Если тебе нужна скорость, см. в сторону использования GPU,
>  
> в том числе и для расчетов.

Я бы рад. Дело в том, что не у всех есть подходящий GPU


 
homm ©   (2008-01-14 13:14) [27]

> Все реализации, даже на ASM которые мне попались я уже обогнал.

Сомневаюсь что есть много реализаций такого кривого подхода, в котором для каждого пикселя считается коэффициент, да еще и в виде процедуры.


> 224 микросекунды на 10000 повторов

Это около 58 смешиваний 1024х768. Кажется это число у меня было близко к тысячи.


 
homm ©   (2008-01-14 13:15) [28]

> [27] homm ©   (14.01.08 13:14)
> Это около 58 смешиваний 1024х768.

в секунду


 
oxffff ©   (2008-01-14 13:17) [29]


> Да я уже добился собственно чего хотел :) Что значит готовые
> реализации? Аппаратное ускорение? Все реализации, даже на
> ASM которые мне попались я уже обогнал.


Не скромно. :)


 
Сергей М. ©   (2008-01-14 13:18) [30]


> DVM ©   (14.01.08 13:09) [26]



> не у всех есть подходящий GPU


Зато с весьма большой долей вероятности у этих всех есть CPU, поддерживающий MMX/XMM/SSE/SSE2


 
DVM ©   (2008-01-14 13:22) [31]


> Сомневаюсь что есть много реализаций такого кривого подхода,
>  в котором для каждого пикселя считается коэффициент, да
> еще и в виде процедуры.

Не много, но есть. Подход нет лучший - спору нет.


> Это около 58 смешиваний 1024х768. Кажется это число у меня
> было близко к тысячи.

Да, 57 с чем то. Ты смешивал что с чем? Битмапы в памяти? И как?


 
DVM ©   (2008-01-14 13:24) [32]


> Сергей М. ©   (14.01.08 13:18) [30]


> Зато с весьма большой долей вероятности у этих всех есть
> CPU, поддерживающий MMX/XMM/SSE/SSE2

Я, к сожалению моему, не владею ASM в достаточной степени.


 
Сергей М. ©   (2008-01-14 13:26) [33]


> DVM ©   (14.01.08 13:24) [32]


> не владею ASM в достаточной степени


Беда, конечно, но не так уж и велика.
Ничто не мешает воспользоваться чьей-либо готовой библиотечной реализацией, использующий тот или иной набор инструкций для достижения сабжа.


 
homm ©   (2008-01-14 13:27) [34]

> [31] DVM ©   (14.01.08 13:22)

Слушай, а это не ты мне советовал глянуть в сторону Graphics32 (или что то похожее)? Вот теперь я советую глянуть на нее :)


 
DVM ©   (2008-01-14 13:30) [35]


> Слушай, а это не ты мне советовал глянуть в сторону Graphics32

Не не я. Мы с тобой дискутировали как то по поводу FastDIB. :)


 
homm ©   (2008-01-14 13:33) [36]

> [35] DVM ©   (14.01.08 13:30)
> Мы с тобой дискутировали как то по поводу FastDIB

Ну возможно я ее и имею ввиду (название не помню). Хоть обогнать мне ее ненамного удалось, но она более универсальна.


 
Ketmar ©   (2008-01-14 14:26) [37]

таки присоединюсь: есть отличная Graphics32, где велосипеды уже написаны и отлажены.


 
Dib@zol ©   (2008-01-14 15:37) [38]

function MCA(FromColor, ToColor: COLORREF; Rate: Byte): COLORREF;
asm
 PUSH EBX;
 PUSH ESI;
 PUSH EDI;
 
 MOV CH, CL;
 SUB CH, 255;
 NEG CH;

 MOV ESI, EAX;
 MOV EDI, EDX;
 MUL CL;
 XCHG EAX, EDX;
 MUL CH;
 ADD AX, DX;
 SHR AX, 8;
 MOV BL, AL;
 ROR EBX, 8;

 MOV EAX, ESI;
 MOV EDX, EDI;
 MOV AL, AH;
 MUL CL;
 XCHG EAX, EDX;
 MOV AL, AH;
 MUL CH;
 ADD AX, DX;
 SHR AX, 8;
 MOV BL, AL;

 MOV EAX, ESI;
 SHR EAX, 16;
 SHR EDI, 16;
 MUL CL;
 XCHG EAX, EDI;
 MUL CH;
 ADD EAX, EDI;
 SHR AX, 8;
 MOV BH, AL;

 ROL EBX, 8;
 MOV EAX, EBX;

 POP EDI;
 POP ESI;
 POP EBX;
end;

Вот. Работает капельку быстрее. 350 мс за 10 миллионов проходов, тогда как сабжевая выдаёт 550 мс. Однако я оч сильно подозреваю, что тут можно обойтись только XOR-ом и битовыми масками. Пока что "масковый" метод даёт довольно приблизительные результаты, однако работает быстрее в 5 раз. Будем работать.


 
Ketmar ©   (2008-01-14 15:41) [39]

всё-таки: а зачем? может, смотреть в сторону аппаратного ускорения, если уж так скорость важна? а то вот на 286 твой код тоже нерабочий…


 
Dib@zol ©   (2008-01-14 16:01) [40]

Нет... увы :( Чем больше отличия Rate от половины, тем больше прут искажения :(

> всё-таки: а зачем? может, смотреть в сторону аппаратного
> ускорения, если уж так скорость важна? а то вот на 286 твой
> код тоже нерабочий…
Дыкъ! Спрошенож было: а можно ли быстрее? Я ответил: "В лоб" - можно, но ненамного. "В обход" - нельзя, ибо глюкаво. Хотя...
ЗЫ На 286-м вряд ли кто-то в здравом уме будет ставить и запускать хотя бы Win 3.11, а тем более уж 9х и далее.
ЗЗЫ Пойду Висту на х286 поставлю :D



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2008.02.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.046 c
2-1201184638
lead-in
2008-01-24 17:23
2008.02.17
TFileStream


15-1200229817
wp2
2008-01-13 16:10
2008.02.17
Что это может быть с компьютером?


15-1200421621
Черный Шаман
2008-01-15 21:27
2008.02.17
Вопрос к Мастерам: как рефакторить такой код.


3-1191490877
Ega23
2007-10-04 13:41
2008.02.17
TDataLink - распознать Insert и Edit


2-1200977987
Skyle
2008-01-22 07:59
2008.02.17
Коллизия имён функций. Общий вопрос.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский