Autor Téma: Násobenie čísla, nie výrazu, jednotkou.  (Přečteno 4344 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Násobenie čísla, nie výrazu, jednotkou.
« kdy: 03-04-2018, 22:54:54 »
Zaujíma ma, či sa to násobenie fyzicky vykoná, alebo mi len priamo vráti číslo. V podstate či tam je niečo ako if ... then
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

99549

  • Host
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #1 kdy: 03-04-2018, 23:08:48 »
Zaujíma ma, či sa to násobenie fyzicky vykoná, alebo mi len priamo vráti číslo. V podstate či tam je niečo ako if ... then

Nechapu co mas na mysli. Jako zda kompilator vygeneruje kod pro nasobeni konstant napr. ve vyrazu jako je tento?

Kód: Delphi [Vybrat]
  1. var
  2.   I: Integer;
  3. begin
  4.   I := 123 * 1;
  5. end;

Pokud ano, a nejsi si jisty, existuje jednoducha pomoc. Spust debugger s breakpointem na takovem radku, a pokud uvidis po stisku CTRL+ALT+D (pripadne zobrazeni stejneho okna pres menu View/Debug Windows/CPU Windows/Disassembly) rozdil mezi kodem pro konstantni hodnotu:

Kód: Delphi [Vybrat]
  1. I := 123;

a pro vyraz:

Kód: Delphi [Vybrat]
  1. I := 123 * 1;

pak kompilator vygeneroval kod pro samotne nasobeni. V tomto pripade bys mel videt pro oba pripady stejny assembly kod, jako napr.:

« Poslední změna: 03-04-2018, 23:40:29 od 99549 »

99550

  • Host
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #2 kdy: 04-04-2018, 00:00:44 »
Dodatek, pokud se opravdu ptas na zpusob generovani kodu pro evaluaci vyrazu slozenych z konstant, pak jsem k tomuto tematu dokumentaci nenasel. Blizke tema je napr. Constant Expressions; to vsak popisuje pouziti funkci jejichz vysledek kompilator dokaze evaluovat v pripade pouziti konstantnich parametru. Tzn. kompilator napr. nebude volat funkci SizeOf pro znamy, definovany typ:

Kód: Delphi [Vybrat]
  1. type
  2.   TMyRecord = record
  3.     TheInteger: Integer;
  4.     TheBoolean: Boolean;
  5.   end;
  6.  
  7. var
  8.   Size: Integer;
  9. begin
  10.   Size := SizeOf(TMyRecord); // kompilator tady nebude volat funkci SizeOf; primo vygeneruje kod s vysledkem velikosti
  11. end;

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #3 kdy: 04-04-2018, 00:22:34 »
V uvedeném případě, kdy výsledkem operace je konstanta, kompilátor vyhodnotí výraz a provede pouze přiřazení ať se jedná o jak složitý výraz chce. Což jde vidět i v tom asm pohledu.

Na delphi.cz jsem kdysi napsal (převzal) seznam optimalizací, co kompilátor v době D2006 prováděl.
Embarcadero MVP - Czech republic

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #4 kdy: 04-04-2018, 00:29:46 »
Jen pro zajímavost:
Kód: Delphi [Vybrat]
  1. i := i * 8;
  2.  
kde i je int, je nahrazen binárním posuvem místo násobení
Kód: Delphi [Vybrat]
  1. Project25.dpr.12: i := i * 8;
  2. 004111C2 A1787E4100       mov eax,[$00417e78]
  3. 004111C7 C1E003           shl eax,$03
  4. 004111CA A3787E4100       mov [$00417e78],eax
  5.  
Embarcadero MVP - Czech republic

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #5 kdy: 04-04-2018, 09:04:58 »
Citace
Nechapu co mas na mysli. Jako zda kompilator vygeneruje kod pro nasobeni konstant napr. ve vyrazu jako je tento?
Mám na mysli to, či sa to násobenie vykoná, alebo sa vynechá. Lebo pri násobení jednotkou to je zbytočná operácia.
Citace
V tomto pripade bys mel videt pro oba pripady stejny assembly kod,
Keď je ten assembler neviem vôbec čítať. Porovnať kód by som mal zvládnuť.
Ešte mi máta hlavou, či sa to bude rôzne spracovávať pre 1 (integer) a 1,0 (real).
Ja viem, že pri dnešných výkonoch CPU to je o ničom. Aj presnosť /pre 1,0) by pre moje účely nemala trpieť. Keď zoberiem do úvahy, že takých násobení môžem mať 10 tisíce, tak sa nad tým zamýšľam.
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #6 kdy: 04-04-2018, 10:06:01 »
Ešte mi máta hlavou, či sa to bude rôzne spracovávať pre 1 (integer) a 1,0 (real).
Ja viem, že pri dnešných výkonoch CPU to je o ničom. Aj presnosť /pre 1,0) by pre moje účely nemala trpieť. Keď zoberiem do úvahy, že takých násobení môžem mať 10 tisíce, tak sa nad tým zamýšľam.

Ano, operace s reálným číslem je pomalá, nepřesná a vůbec.

Ale pořád platí že něco jako

x *10 *23*4*34 se provede tak, se to přeloží x* výsledek násobením konstantou
Embarcadero MVP - Czech republic

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #7 kdy: 04-04-2018, 10:45:35 »
Ale pořád platí že něco jako

x *10 *23*4*34 se provede tak, se to přeloží x* výsledek násobením konstantou
Ano, vzdycky plativalo, ze co jde vyhodnotit jako invariant v dobe prekladu, tak se pri prekladu vyhodnoti. Jinak by to snad ani nebyl prekladac, ale nejaka parodie.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #8 kdy: 04-04-2018, 11:19:14 »
Teraz ešte neviem, či to násobenie bude v Delphi, alebo ako súčasť SELECT-u vo FireBirde ;D
Prerábam jeden výpočet, kde to je teraz v Delphi. Mám snahu to presunúť na DB. Je jasné, že keď pracujem s datasetom, tak sa o invariant nejedná.
Ja neviem posúdiť čo je výhodnejšie:
  • čosi * 1,0 či
  • if ... then ... else ... (Delphi) alebo
  • case when ... then ... else ... (FB)
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3530
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #9 kdy: 04-04-2018, 11:27:02 »
Teraz ešte neviem, či to násobenie bude v Delphi, alebo ako súčasť SELECT-u vo FireBirde ;D
Prerábam jeden výpočet, kde to je teraz v Delphi. Mám snahu to presunúť na DB. Je jasné, že keď pracujem s datasetom, tak sa o invariant nejedná.
Ja neviem posúdiť čo je výhodnejšie:
  • čosi * 1,0 či
  • if ... then ... else ... (Delphi) alebo
  • case when ... then ... else ... (FB)
Na to se v obecne rovine bude jen stezi odpovidat, protoze to bys musel presne nastinit test case. Ale jednotlive operace podle rychlosti jsou:
1. if --- then --- else (kriticka je podminka)
2. cosi * 1,0
3. case when ..., protoze na strane DB serveru se to znovu preklada a interpretuje (presun operaci na RDBMS je v usetreni overheadu s tahanim dat na klienta)

Ale kdybys ty varianty zkusil a zmeril si to, tak to za cas straveny dotazy na foru davno vis ;-)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #10 kdy: 04-04-2018, 12:59:43 »
Citace
Ale kdybys ty varianty zkusil a zmeril si to, tak to za cas straveny dotazy na foru davno vis ;-)
Nemám tak veľkú sadu údajov. Len 10 bytov. To je veľmi málo. Potreboval by som ich 100. V tej podmienke bude vždy cosi = 1
Zhruba:
  • 10 bytov = 2 000 záznamov. Ja ich mám asi 1 200
  • 100 bytov = 20 000 záznamov
a to vo viacerých tabuľkách. Preto nad tým špekulujem už teraz. Ale tu optimalizáciu si asi nechám až keď nastane ten správny čas.
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #11 kdy: 05-04-2018, 15:34:34 »
Excellent
Rated 1 time
Citace
Ale kdybys ty varianty zkusil a zmeril si to, tak to za cas straveny dotazy na foru davno vis ;-)
Nemám tak veľkú sadu údajov. Len 10 bytov. To je veľmi málo. Potreboval by som ich 100. V tej podmienke bude vždy cosi = 1
Zhruba:
  • 10 bytov = 2 000 záznamov. Ja ich mám asi 1 200
  • 100 bytov = 20 000 záznamov
a to vo viacerých tabuľkách. Preto nad tým špekulujem už teraz. Ale tu optimalizáciu si asi nechám až keď nastane ten správny čas.

Kdyby jsi tohle napsal na začátku, tak bych tě poslal ...

Embarcadero MVP - Czech republic

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #12 kdy: 05-04-2018, 21:05:41 »
Citace
Kdyby jsi tohle napsal na začátku, tak bych tě poslal ...
:) Ako dobre, že som to nenapísal.
Teraz vážne. Tých 20 tisíc záznamov sa nejaví veľa. Ale výpočet je dosť prácny, a tie záznamy sa znásobujú. Výsledné SQL sa skladajú z niekoľkých subselectov. A ja netuším ako to v konečnom dôsledku dopadne. Niečo také som ešte nerobil. Vždy to boli z pohľadu prácnosti jednoduché veci. Preto sa tu občas, pre istotu do budúcna, pýtam na takéto prkotiny. Aby som v prípade, že výpočet bude trvať príliš dlho, vedel kde to/čo mám riešiť. Je to vlastne taký prieskum.
Kvôli optimalizácii som si nainštaloval AQtime. Jeho čas ešte nenastal.
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #13 kdy: 06-04-2018, 00:01:57 »
Jen tak pro zajímavost, na jaké časy se chceš pro zpracování těch 20 tis záznamů dostat?
Embarcadero MVP - Czech republic

99588

  • Host
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #14 kdy: 06-04-2018, 03:07:37 »
Jen tak pro zajímavost, na jaké časy se chceš pro zpracování těch 20 tis záznamů dostat?

Preci na ty nejlepsi ;D

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #15 kdy: 06-04-2018, 08:47:44 »
Citace
Jen tak pro zajímavost, na jaké časy se chceš pro zpracování těch 20 tis záznamů dostat?
Ja to ešte netuším. Najprv musím spojazdniť celý výpočet. Potom si nahodiť dostatok údajov. Až potom uvidím, či je potrebné vôbec niečo riešiť. Len si teraz zháňam nejaké informácie.
V prílohe je obrázok, čo všetko riešim. Pre veľmi hrubú predstavu.
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline Ondřej Pokorný

  • Guru
  • *****
  • Příspěvků: 815
  • Karma: 59
    • Verze Delphi: Primárně Lazarus, jinak D7 až aktuální
    • Kluug.net
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #16 kdy: 06-04-2018, 09:03:12 »
Tak násobení jedničkou není zrovna složitá operace. Povětšinou to zvládnu i z hlavy a ani počítačku nepotřebuju.
Embarcadero Technology Partner

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #17 kdy: 06-04-2018, 10:45:06 »
Citace
Jen tak pro zajímavost, na jaké časy se chceš pro zpracování těch 20 tis záznamů dostat?
Ja to ešte netuším. Najprv musím spojazdniť celý výpočet. Potom si nahodiť dostatok údajov. Až potom uvidím, či je potrebné vôbec niečo riešiť. Len si teraz zháňam nejaké informácie.
V prílohe je obrázok, čo všetko riešim. Pre veľmi hrubú predstavu.

LOL, ten obrázek mi leccos vysvetluje, já jsem si od začátku myslel, že 10 bytov znamená slovensky 10 bajtů, nikoliv 10 obytných jednotek.

Už mlčím - ale být tebou bych spíše se začal ptát až budeš mít pocit, že chceš něco zrychlit, než na začátku zjišťovat teoretické věci.
Embarcadero MVP - Czech republic

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7426
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #18 kdy: 06-04-2018, 11:42:05 »
Citace
já jsem si od začátku myslel, že 10 bytov znamená slovensky 10 bajtů
:D Aké je to programovanie záludné. Ja s tým žijem a taká možnosť mi neprišla na um.
Druhú vetu si beriem k srdcu.
Win11 64b, Delphi 12.2, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline našinec

  • Hrdina
  • ****
  • Příspěvků: 423
  • Karma: 5
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #19 kdy: 06-04-2018, 13:13:25 »
Tak tato vzniká komunikační šum.  ;D  Ale s ohledem na to, co věčně řeší Stano, tak mi bylo hned jasné, že se jedná o obytné jednotky, zatímco u Radkova příspěvku bylo hned jasné, že hovoří o veličině. Každopádně s ohledem na následující reakce jsem zapochyboval o správnosti svých úvah.
Jinak, nevím, zda jsem správně pochopil Stanův dotaz, ale dle mého matematický úkon proběhne vždy. Neproběhne, pokud to ošetříš. Otázkou je, zda tím něco získáš.  ;)

--------Pozdější dovětek------------

Mimochodem Stano, pojem 'jednotka' se v češtině používá právě v souvislosti s bydlením - bytová jednotka.  ;)  ;D
« Poslední změna: 06-04-2018, 13:22:23 od našinec »

Offline vandrovnik

  • Padawan
  • ******
  • Příspěvků: 1587
  • Karma: 52
    • Verze Delphi: 11.3
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #20 kdy: 06-04-2018, 14:25:28 »
Jinak nějakou optimalizaci si dělá i procesor, takže bych to v kódu pro 20 tisíc položek rozhodně neřešil.
Násobení jedničkou mu jde rychleji než násobení nějakým ošklivým číslem.

U mě to vyšlo zhruba 35578919 tiků pro násobení jedničkou a 35653693 tiků pro násobení tím ošklivým číslem.


Kód: Delphi [Vybrat]
  1.  var a:integer;
  2.      t:tStopWatch;
  3.      x,y,z:UInt64;
  4.  begin
  5.  t:=t.Create;
  6.  x:=$cfcfcfcfcfcfcfcf;
  7.  y:=1;
  8.  t.Start;
  9.  for a:=1 to $7FFFFFFF do z:=x*y;
  10.  t.Stop;
  11.  v1.Caption:=IntToStr(t.ElapsedTicks);
  12.  //
  13.  x:=$cfcfcfcfcfcfcfcf;
  14.  y:=$fcfcfcfcfcfcfcfc;
  15.  t.Reset;
  16.  t.Start;
  17.  for a:=1 to $7FFFFFFF do z:=x*y;
  18.  t.Stop;
  19.  v2.Caption:=IntToStr(t.ElapsedTicks);
  20.  


Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 3532
  • Karma: 112
    • Verze Delphi: D2007, DXE + 2 poslední
    • O Delphi v češtině
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #21 kdy: 06-04-2018, 14:34:03 »
vandrovnik: no a kdyz uz jsi v tom, tak jsi to mohl zkusit i v realnych číslech proti 64bit kompilatoru a s
Kód: Delphi [Vybrat]
  1. {$EXCESSPRECISION ON} nebo {$EXCESSPRECISION OFF}
  2.  

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Floating_point_precision_control_%28Delphi_for_x64%29
Embarcadero MVP - Czech republic

Offline vandrovnik

  • Padawan
  • ******
  • Příspěvků: 1587
  • Karma: 52
    • Verze Delphi: 11.3
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #22 kdy: 06-04-2018, 16:05:59 »
Excellent
Rated 2 times
No, nedalo mi to :-) Musím říct, že některé výsledky mě docela překvapily - třeba že single není rychlejší než double a že single víceméně stejně rychlý jako nativní integer, natož jak dopadne, když si člověk nenastaví EXCESSEXPRESSION OFF... (Hádám, že pokud by se měly např. počítat goniometrické funkce, tak by už single rychlejší bylo.) To měření času není moc přesné, i když se ve správci úloh nastaví priorita Reálný čas, stejně výsledky dost lítají. Testováno na obstarožním i7 920 @ 2,67 GHz, Win 10 64bit.

-----------

32bit app, uint32,
x:=12345678; y:=1; -------> 13957016
x:=12345678; y:=87654321; -------> 13998208

32bit app, uint64,
x:=1234567812345678; y:=1; -------> 35580995
x:=1234567812345678; y:=8765432187654321; -------> 35651912

32bit app, single,
x:=1234.5678; y:=1; -------> 14020182
x:=1234.5678; y:=8765.4321; -------> 14016425

32bit app, double,
x:=1234.5678; y:=1; -------> 12151941
x:=1234.5678; y:=8765.4321; -------> 12156582

------------

64bit app, uint32,
x:=12345678; y:=1; -------> 13163029
x:=12345678; y:=87654321; -------> 13419768

64bit app, uint64,
x:=1234567812345678; y:=1; -------> 13330492
x:=1234567812345678; y:=8765432187654321; -------> 13453193

64bit app, single, {$EXCESSPRECISION OFF}:
x:=1234.5678; y:=1; -------> 12677965
x:=1234.5678; y:=8765.4321; -------> 13731444

64bit app, single, {$EXCESSPRECISION ON}, popř. {$EXCESSPRECISION... ručně nenastaveno:
x:=1234.5678; y:=1; -------> 22079486
x:=1234.5678; y:=8765.4321; -------> 22047472

64bit app, double, {$EXCESSPRECISION OFF}:
x:=1234.5678; y:=1; -------> 14053849
x:=1234.5678; y:=8765.4321; -------> 14060714

64bit app, double, {$EXCESSPRECISION ON}, popř. {$EXCESSPRECISION... ručně nenastaveno:
x:=1234.5678; y:=1; -------> 14023874
x:=1234.5678; y:=8765.4321; -------> 14024711

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1574
  • Karma: 37
    • Pepak.net
Re:Násobenie čísla, nie výrazu, jednotkou.
« Odpověď #23 kdy: 08-04-2018, 20:40:42 »
Ano, vzdycky plativalo, ze co jde vyhodnotit jako invariant v dobe prekladu, tak se pri prekladu vyhodnoti. Jinak by to snad ani nebyl prekladac, ale nejaka parodie.
No, vždycky platívalo... Co jsem si to kdysi zkoušel u stringů, tak tam to platilo jen v jednom směru - konst1 + konst2 + var1 se převedlo na konst3 + var, ale var1 + konst1 + konst2 zůstalo beze změny.