kategorie: ANSI C, Asembler
[#1] [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?
Cześć,
Mój bufor kolorów to u_int32, RGBA, A nie używam oczywiście.
Czy można jakoś przyśpieszyć operacje na kolorach bez wyłuskiwania RGB?
Najbardziej zależy mi na obliczeniu średniej z dwóch takich kolorów.

Do tej pory robiłem tak, jeśli chciałem zmienić intensywność całego pixela:

output_buffer_32[index] =   
                         intensity_premultipled[texture_pixel >> 16 & 0x0ff]  << RC_ch1 |
                         intensity_premultipled[texture_pixel >>  8 & 0x0ff]   << RC_ch2 |
                         intensity_premultipled[texture_pixel          & 0x0ff]   << RC_ch3;



czyli najpierw wyłuskiwałem każdy RGB osobno a potem znowu składałem w całość robiąc shifty (przy czym swifty były jako zmienne RC_ch1, 2,3 żeby zawsze mi sie kolory zgadzaly w zaleznosci of formatu pixela, i ustawiałem je wcześniej)

Teraz teraz zamiast jednej tablicy zrobiłem 3 tablice ktore na wyjściu mają już przesunięty kolor na właściwe miejsce, więc pozbyłem się przesunięcia i wydajność mocno wzrosła:

output_buffer_32[index] = intensity_premultipled_CH1[texture_pixel >> 16 & 0x0ff] |
                                        intensity_premultipled_CH2[texture_pixel >>  8 & 0x0ff] |
                                        intensity_premultipled_CH3[texture_pixel       & 0x0ff];



Natomiast chciałem spróbować zrobić coś takiego. Mój bufor kolorów byłby wypełniony co drugi pixel - po pierwszym przejściu (to pixele otrzymane w wyniku obliczeń). Natomiast chciałbym na koniec zrobić drugie przejście, które by interpolowało pomiędzy istniejącymi już kolorami. Zakładam, że
guzik bym zyskał na koniec, ale wale sprawdzić lub zapytać. Sens miało by to jeśli operacja interpolacji dałaby się zrobić jakoś szybko. Może są jakieś asemblerowe sztuczki? Poniżej schematycznie o co chodzi:




ps.
zamiana bufora kolorów z u_int32 na unię z osobnymi komponentami typu char r,g,b,a nie wiele daje..



Ostatnia aktualizacja: 10.04.2021 16:52:24 przez mateusz_s
[#2] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@mateusz_s, post #1

tu coś znalazłem ale jeszcze nie przetestowałem:
https://stackoverflow.com/questions/8440631/how-would-you-average-two-32-bit-colors-packed-into-an-integer
[wyróżniony] [#3] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@mateusz_s, post #2

Uzywam takiej, bardzo szybkiej metody:

uint32_t AveragePixels(uint32_t a, uint32_t b)
{
return (((a ^ b) & 0xfffefefe) >> 1) + (a & b);
}
[wyróżniony] [#4] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@docent, post #3

To jest najszybsze. Maska jest potrzebna żeby najmłodszy bit z każdej ósemki nie wyjechał przy przesuwaniu do sąsiedniego bajtu.

Ostatnia aktualizacja: 10.04.2021 20:14:06 przez Kefir_Union
[#5] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@Kefir_Union, post #4

@docent @Kefir_Union
Dobra, dzięki Panowie :)
[#6] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@docent, post #3

Jeśli to faktycznie są 24 bity, a nie 32, to po co & 0xfffefefe przed >>1 jak powinno wystarczyć & 0x7f7f po >>1 (górnego słowa nie trzeba ruszać)? Chyba że przewidujemy jakieś śmieci w najstarszym bajcie. Choć pewnie ze wzrosten modelu cpu ma to coraz mniejsze znaczenie.
[#7] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@BigBang, post #6

To zależy co z tym zrobi kompilator. Jeśli przed pętlą wrzuci maskę do rejestru to rozmiar AND będzie bez znaczenia. Jeśli użyje stałej to będzie strata dwóch cykli na 020/030.
[#8] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@Kefir_Union, post #7

Generalnie ten drugi przebieg z uśrednianiem wyszedł
Mi mniej wydajnie, tak jak myślałem, niż jak robie teraz.
Jeszcze spróbuje drugiego podejścia na zasadzie np. Robienia tego blokami 8x8, a nie na chama cały bufor ale pewnie będzie podobnie..
[#9] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@BigBang, post #6

O ile dobrze pamietam, to maska 0x7f7f , zgodnie ze standardem jezyka, zostanie automatycznie wypromowana do typu unsigned int i operacja zostanie wykonana na typie unsigned int. W rezultacie zostanie utracona skladowa koloru z gornego slowa.
[#10] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@docent, post #9

A to by trzeba było sprawdzić, napisałem tylko ogólną ideę, że wystarczy dolne słowo "zANDować", w sumie bardziej myśląc asemblerowo jednak.
[#11] Re: [ASM, C] Czy można przyśpieszyć operacje na kolorach RGB zapisanych w 32bit?

@docent, post #3

Stanęło na:
#define AVERAGE(a, b)   ( ((((a) ^ (b)) & 0xfefefefe) >> 1) + ((a) & (b)) )


0xfffefefe - robiło jakieś babole, pewnie ze względu na format textury BGR,

poniżej kilka porównań, ale lepiej jest jednak bez tej interpolacji, bo z daleka rozmywa i wydajność jednak spada:

trzeab powiększyć do 100% obrazek zeby roznice widac bylo



Ostatnia aktualizacja: 12.04.2021 00:41:44 przez mateusz_s
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem