Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.02.17;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.019 c
15-1200295245
TUser
2008-01-14 10:20
2008.02.17
Ашипка вышла :)


15-1200305796
Stilet
2008-01-14 13:16
2008.02.17
Как проинсталить Perl?


8-1173611587
Игорь 2222
2007-03-11 14:13
2008.02.17
Что то похожее на Paint


1-1188308666
readline();
2007-08-28 17:44
2008.02.17
Unicode, UTF8


15-1200159007
anton773
2008-01-12 20:30
2008.02.17
listbox.items.add в .NET