Program stosujący filtr Laplace'a w asemblerze

0

Witam,
Mam stworzyć program który stosuje filtr Laplace'a na bitmapie w odcieniach szarości. Wczytywanie obrazu wykonuje się w c#, a stosowanie filtru ma odbywać się w asemblerze.
Na razie stworzyłem coś takiego. Bitmapa jest konwertowana na tablicę byte'ów. Ładuję otoczenie każdego piksela do tablicy i dla każdego piksela jest wywoływana funkcja w asemblerze

for (int i = 1; i < wysokosc - 1; i++)
{
    for (int j = 1; j < szerokosc - 1; j++)
    {
        dane[0] = tabPixel2[(((i + 1) * szerokosc) + j) - 1];   // Ładowanie otoczenia piksela do tablicy
        dane[1] = tabPixel2[(((i + 1) * szerokosc) + j)];
        dane[2] = tabPixel2[(((i + 1) * szerokosc) + j) + 1];
        dane[3] = tabPixel2[((i * szerokosc) + j) - 1];
        dane[4] = tabPixel2[((i * szerokosc) + j) + 1];
        dane[5] = tabPixel2[(((i - 1) * szerokosc) + j) - 1];
        dane[6] = tabPixel2[(((i - 1) * szerokosc) + j)];
        dane[7] = tabPixel2[(((i - 1) * szerokosc) + j) + 1];

        danysrodek[0] = tabPixel2[((i) * szerokosc) + j];

        LAPLACE(dane, maska, danysrodek, maskasrodek); // Wywołanie procedury w asemblerze

        if (maskasrodek[0] > 255) // Obliczona w asemblerze wartość jest zwracana w miejscu gdzie podaje się maskę dla środkowego piksela
        {
            maskasrodek[0] = 255;
        }
        else if (maskasrodek[0] < 0)
        {
                maskasrodek[0] = 0;
        }

        tabPixelWyj[(i * szerokosc) + j] = (byte)maskasrodek[0];
    }
}

Tutaj kod w asemblerze:

LAPLACE proc
	movups XMM0, [RCX] ;załaduj otoczenie (8 pikseli)
	movups XMM1, [RDX] ;załaduj maskę
	mov RAX, [R8] ;załaduj piksel środkowy
	mov RBX, [R9] ;załaduj maskę dla środkowego piklesa

	PMULLW XMM0, XMM1 ;mnożenie

	PHADDW XMM0, XMM0
	PHADDW XMM0, XMM0 ;sumowanie (kilka razy aby wszystko się zsumowało)
	PHADDW XMM0, XMM0

	MOVD RDX, XMM0 ;przenieś wynik do RDX
	IMUL RAX, RBX  ;pomnóż środkowy piksel przez maskę
	SUB RAX, RDX ;odejmnij wartość sumy otoczenia od środkowego piksela
	mov [R9], RAX ;przenieś gotowy wynik do zwrotu
	ret
LAPLACE endp

Taki kod wykonuje się strasznie długo, a chodzi o to aby to zrobić optymalnie.
Prosiłbym o jakieś pomysły

1

Na pewno dobrze zrozumiałes zadanie?

Krótkie odpalenie ASM w pętli N*M w zarządzanym kodzie C# to chyba nie jest optymalizacja. Koszty przełącznia sie są znaczne, nawet wieksze niż by kontunować w wysokopoziomowym C#

ps. nie pytaj mnie "jak", od wielu lat nie asemblowałem na Intelach, a i numeryka też wyleciała z głowy. Tym niemniej mam zdecydowane przekonanie: nie o to chodzi w zadaniu
Sądzę, że powinno ci wyjsc 50-100 linii w C# (przygotowanie danych) i poważne setki linii ASM (algorytm na macierzy)

0

Źle to ująłem. Chodzi mi o to aby kod w asemblerze wykonywał się jak najszybciej. Tutaj funkcja w asm jest wywoływana dla każdego piksela, a lepiej aby była wywoływana raz, przekazując całą tablicę i tam działy się wszyskie działania na niej, na końcu przekazując tablicę z przetworzonym obrazem

1 użytkowników online, w tym zalogowanych: 0, gości: 1