[Delphi/ assembler] stukje code optimaliseren

Pagina: 1
Acties:

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:44

Tomatoman

Fulltime prutser

Topicstarter
Ik heb in Delphi code geschreven die checksums uitrekent van een TrueType font file. Op zich werkt dat allemaal prima, maar de code kan vast wel wat sneller worden.

Het lullige van TrueType fonts is dat de byte-volgorde van de Mac afkomstig is en dus precies omgekeerd is aan de byte-volgorde van een pc. Om de (32-bits) checksum te berekenen, moet ik daarom een paar miljoen keer vier bytes van plaats verwisselen. Dat doet de volgende functie:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  TBigLongword = packed record // 32-bit unsigned integer
    HiWordHiByte: Byte;
    HiWordLoByte: Byte;
    LoWordHiByte: Byte;
    LoWordLoByte: Byte;
  end;

function BigLongwordToLongword(const BigLongword: TBigLongword): Longword;
begin
  Result := (BigLongword.HiWordHiByte shl 24) or
    (BigLongword.HiWordLoByte shl 16) or
    (BigLongword.LoWordHiByte shl 8) or
    BigLongword.LoWordLoByte;
end;

Delphi maakt dit ervan:
Afbeeldingslocatie: http://home.planet.nl/~robin.gerrets/linked/biglongwordtoword-assember.gif

Hoe kan ik deze functie een stuk sneller maken?

Een goede grap mag vrienden kosten.


Verwijderd

Niet veel in ieder geval. De delphi compiler maakt in ieder geval redelijk geoptimaliseerde code. Je zou range-checking e.d. uit kunnen zetten bij compiler opties.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 02-09 19:44

Gerco

Professional Newbie

-- [hier stond iets doms] --

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
ipv 00464DB3-00464DBD:
code:
1
2
mov dh,[ebp-$03]
or edx,[ebp-$02]

lijkt mij sneller.

en 00464DCC-00464DCF lijken me een beetje nutteloos. dit dus:
code:
1
2
mov [ebp-$08],eax
mov eax,[ebp-$08]

Verwijderd

1) je moet die or's eruit zien te krijgen
2) geen functie gebruiken, maar inline zetten (of procedure als het niet anders kan)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

bswap gebruiken, daar is die instructie voor bedoeld :)
code:
1
bswap eax

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
hehe , das wel iets simpeler :)

Verwijderd

Op zondag 09 juni 2002 00:25 schreef .oisyn het volgende:
bswap gebruiken, daar is die instructie voor bedoeld :)
code:
1
bswap eax
ik kwam hem net tegen:
code:
1
2
3
4
function IntSwap(Source: Integer): Integer;
asm
  bswap eax
end;

  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:44

Tomatoman

Fulltime prutser

Topicstarter
Bedankt allemaal, het gaat erop lijken :). Inmiddels heb ik zelf voor het eerst van mijn leven een stukje assembler code geschreven en ben ik tot het volgende gekomen:
code:
1
2
3
4
5
6
function BigLongwordToLongword(const BigLongword: TBigLongword): Longword;
asm
  rol     ax,8      { swap LoWordHiByte and LoWordLoByte }
  shld    eax,eax,16    { swap (unaltered) HiWord and (altered) LoWord }
  rol     ax,8      { swap HiWordHiByte and HiWordLoByte }
end;

Dat scheelt al heel wat clock cycles. Ik heb het even uitgerekend.
code:
1
2
3
4
5
6
7
8
9
OUDE CODE:              |  NIEUWE CODE:
                      |
coderegel      clock cycles  |  coderegel      clock cycles
=========      ============  |  =========      ============
begin                11  |  asm               0
Result := [...]      50  |  [rol, shld, rol]     3+3+3=  9
end;                22  |  end;             12
                 _____  |                  _____
totaal              83  |  totaal               21

Da's bijna 75% tijdwinst >:). Maarreh, die bswap ken ik niet (hij zal wel bloedsnel zijn). Ik gebruik deze handleiding en daar staat 'ie niet in. Is bswap een nieuwe operator? En wat betekent dat als iemand mijn programma op een prehistorische 386 gebruikt?

Een goede grap mag vrienden kosten.


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
bswap werkt vanaf 486

  • JayTaph
  • Registratie: Oktober 1999
  • Laatst online: 28-11-2025

JayTaph

Portability is for canoes.

(jarig!)
Nog sneller is het natuurlijk om hiervan geen apartie functie te maken. Dat scheelt 1x een dword (of in het ergste geval 4x een byte) die gePUSHed moet worden, 1x een CALL naar de functie, 1x stack opzetten en 1x RETurn en 1x weer je stack decreasen. Waarbij vooral die PUSH, CALL en RET processortik-vreters zijn. Die kun je dus beter wegwerken dan een aantal xor'etjes meer of minder. :)

edit:

* JayTaph ziet nu 3 enge POP's in je debug-schermpje staan... over zonde van je tikken gesproken :)

Yo dawg, I heard you like posts so I posted below your post so you can post again.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:44

Tomatoman

Fulltime prutser

Topicstarter
Op zondag 09 juni 2002 01:46 schreef JayTaph het volgende:
Nog sneller is het natuurlijk om hiervan geen apartie functie te maken. [...]
Helemaal mee eens, eigenlijk had ik het al zo geïmplementeerd. Maar om het topic een beetje overzichtelijk te houden, heb ik er een aparte functie van gebouwd.

BTW, via Google vond ik de volgende quote over bswap:
On the 80486, this instruction takes one clock cycle during execution.
Lijkt me moeilijk om dit nog te overtreffen. :)

Een goede grap mag vrienden kosten.

Pagina: 1