Vinnaren i pepparkakshustävlingen!
2003-08-31, 13:36
  #1
Medlem
Bjerts avatar
Tjohopp, jag har suttit och lekt lite med inline Assembly (inte Assembler!) i Visual C++ och kört fast i min optimering. Funktionen jag skriver på är en dummy-function som inverterar en bild. Nu har kommer jag dock inte längre med min optimering, så jag skulle vilja ha era tips.

Algoritm:
Eftersom jag vill invertera alla färgerna gäller det alltså att invertera alla element i arrayen. När jag inte behöver bry mig om vilka som ska inverteras kan jag läsa två dword (double word) per loop. Detta är för att jag ska kunna para intruktionerna.
När jag parat instruktionerna blir koden lite rörigare med jag får hoppas att in förstår ändå :-)
Nåväl jag har inga mer ideer så jag skull gärna vilja ha era tips.

Jag har hämtat ganska så mycket information om optimering från Agner Fogs guide. http://www.agner.org/assem/pentopt.zip

Här kommer koden:
Kod:
struct rgb {
	unsigned char	red;
	unsigned char	green;
	unsigned char	blue;
};

void InvertImage_optimized4(rgb *picture, unsigned int width, unsigned int height) {

__asm {
	push	ebx

	mov	ebx, [picture]

	// check the alignment (aligned by 8)
	mov	eax, ebx
	test	eax, 7
	jnz	ready

	mov	eax, dword ptr [width]	// width
	imul	eax, dword ptr [height]	// width * height
	imul	eax, 3			// width * height * sizeof(unsigned char) * 3
	add	eax, ebx			// add base address
	mov	ecx, eax


	jmp	first_time

	// read two dword per loop
main_loop:
	mov	dword ptr [ebx-4], eax	// U
first_time:
	mov	edx, dword ptr [ebx]		// V (pairs)

	add	ebx, 4			// U
	xor	edx, 0FFFFFFFFh		// V (pairs)

	mov	eax, dword ptr [ebx]	// U
	add	ebx, 4			// V (pairs)

	xor	eax, 0FFFFFFFFh		// U
	mov	dword ptr [ebx-8], edx	// V (pairs)

	cmp	ebx, ecx			// U
	jb	main_loop			// V (pairs)

	mov	dword ptr [ebx-4], eax
ready:

	pop	ebx
}

}

Jag har säkert stavat nått engelskt ord fel...
Citera
2003-08-31, 17:10
  #2
Medlem
Stockos avatar
Kör med mmx-instruktioner (movq och pxor) istället.
Citera
2003-08-31, 17:30
  #3
Medlem
Bjerts avatar
Citat:
Ursprungligen postat av Stocko
Kör med mmx-instruktioner (movq och pxor) istället.

Tackar och bockar. Nu blir det till att skriva om det och testa.
Citera
2003-08-31, 18:16
  #4
Medlem
Bjerts avatar
Med MMX

Det tog lite tid men nu är det färdigt.. Tiden för ett antal iterationer minskade från ~240 till ~140 (ingen speciell enhet). För att ytterligare snabba på det borde jag kunna göra flera "inverteringar" per loop.
Jag kom dock inte på någon bra lösning för att ladda in 0xFFFFFFFFFFFFFFFF till ett MMX-register. Är det någon som har några bra tips?

Den nya koden:
Kod:
void InvertImage_optimized5(rgb *picture, unsigned int width, unsigned int height) {

unsigned int dummy[2];

dummy[0] = 0xFFFFFFFF;
dummy[1] = 0xFFFFFFFF;

__asm {

	push	ebx

	mov	ebx, [picture]

	// check the alignment (aligned by 8)
	mov	eax, ebx
	test	eax, 7
	jnz	ready

	mov	eax, dword ptr [width]
	imul	eax, dword ptr [height]
	imul	eax, 3
	add	eax, ebx
	mov	ecx, eax

	movq	mm1, [dummy]

	// read a quad word per loop
main_loop:			
	movq	mm0, [ebx]
	pxor	mm0, mm1
	movq	[ebx], mm0

	add	ebx, 8
	cmp	ebx, ecx
	jb	main_loop

ready:

	pop	ebx
}

}
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback