» »

Množenje v C

Množenje v C

BladeRunner ::

Pozdravljeni. Imam del kode, kjer je ogromno množenja. Hkrati pa bi želel, da se ta del izvede zelo hitro.

Imam recimo takole:

b=a*a*a;
d=a*b+a*c;
...

in pa:

t=n*n*n;
t3=t*t*t;
...

Ker je tega kar veliko me zanima ali obstaja mogoče hitrejši način, da bi poračunal take produkte? Funkcija pow(a, 3) je bistveno počasnejša od recimo a*a*a.

Zasledil sem, da je možno definirati operacijo nekako tako:

#define CUBE(a) a*a*a

in potem v programu namesto a*a*a napišem samo CUBE(a), sintaktično je očitno to pravilno, samo rezultat je popolnoma napačen. Ima še kdo kako idejo kaj bi lahko pospešilo množenje?

smoke ::

Pozdravljen!

Kakšno množenje se bo pa pojavljalo? Vedno samo a*a*a? Al je še kaj druga?

BladeRunner ::

Operacija je enaka, operandi pa se menjajo. Takole nekako:

c1=a1*a1*a1;
r=r1*r1*r1;
e=f*f*2.0
e1=f2*f2+f3*f3
d4=d*d*d*d
...

Lahko bi seveda uporabil pow(), vendar je bistveno počasneje.

smoke ::

Lahko ti napišem kodo v assemblyju če hočeš samo bi rabil malo več informacij :) Matematični koprocesor x87 je baje hiter :)

technolog ::

Izvedlo se bo tako hitro, kot je to sposoben procesor.

Edino, kar lahko narediš je, da ne računaš istih stvari večkrat. Recimo:

x=a*a*a*b;
y=a*a*a*c;

daj v:

temp=a*a*a;
x=temp*b;
y=temp*c;

BladeRunner ::

Aha potem je to že to kar se je dalo dosečt. To z temp sem že naredil. Mislil sem, da se da mogoče še kaj nardit glede tega. Asemblerja ne bi zaenkrat.... :)

celebro ::

Če imaš na voljo večjederni procesor, in dele kode, ki so medsebojno neodvisni, bi se mogoče splačalo uporabiti več niti.

Če množiš floate, bi se pa dalo uporabiti integerje (da npr. float pomnožiš s 100, rezultat pa na koncu ustrezno zdeliš) bi tudi lahko bilo hitreje.

Senitel ::

Ja če samo zamenjaš dve množenji z makrojem, ne prihraniš ničesar. Lahko rečeš, da je d = a*(b+c) in prihraniš množenje, za malo več registrov (ampak je verjetno že sam compiler dovolj pameten za kaj takega).
Aseembly pozabi, razen če misliš SSE kodo pisat.
Multithreading ja, če lahko zadevo razbiješ na dovolj velike neodvisne bloke.

technolog ::

Itak bi ti pameten C/C++ compiler (odmisli MS zadeve) zna optimizirat tvojo kodo tako dobro, da ne pridobiš ničesar (ali minimalno) če bi pisal v zbirniku.

To, kar je napisal celebro je tudi dober razmislek. Makroti ne delajo nič drugega kot upočasnijo proces buildanja in večinoma poenostavijo izvorno kodo.

Zgodovina sprememb…

jype ::

technolog> odmisli MS zadeve

Microsoftov prevajalnik pa res ni slab - morda je le malce nekonvencionalen, če si vajen gcc in icc.

Brane2 ::

V bistvu bi bilo pametno poznat celoto.

Ziher nis amo teh par ukazov. Zelo je odvisno od konteksta.

SSE ti lahko pomaga, če lahko stlačiš operande in operacije v ta kontekst. Pomembna je tudi medsebojna odvisnost operandov pa količina in struktura.

Če gre za recimo pakete podatkov, lahko obdelaš vsakega na svojem coreu. Ravno tako ni vseeno kakčni so podatki.

Tam imaš enega od parametrov 2.0. kar pomeni, da mogoče lahko izvedeš množenje kot simpl šiftanje. Ali pa prištevanje drugega operanda k samemu sebi itditd.
On the journey of life, I chose the psycho path.

hexor ::

Rekurzivno množenje. :)
RootMachine ;)

MrBrdo ::

Če večkrat uporabljaš iste podatke, lahko probaš tudi s CUDA, če imaš to možnost... Npr. če imaš več iteracij ali kaj takega, če imaš v vsakem izračunu druge podatke potem se ti verjetno ne bo splačalo, ker moraš vse podatke najprej prenest v pomnilnik grafične kartice. Ko pa so enkrat tam imaš se mi zdi 512 procesorjev na voljo :) Množenje obvladajo :P
Razen več niti kej drugega verjetno ne moreš, ker compiler ti verjetno že dovolj dobro optimizira, da v assemblyju nebi nič pridobil. Edino kar lahko probaš če imaš slučajno to množenje v funkciji da daš ven iz funkcije ali uporabiš "inline" keyword.
MrBrdo

bigbada ::

Uporabi OpenMP in naredi da se bo mnozenje izvajalo paralelno oz. vzporedno.

Genetic ::

BladeRunner je izjavil:

...
Zasledil sem, da je možno definirati operacijo nekako tako:

#define CUBE(a) a*a*a

in potem v programu namesto a*a*a napišem samo CUBE(a), sintaktično je očitno to pravilno, samo rezultat je popolnoma napačen. Ima še kdo kako idejo kaj bi lahko pospešilo množenje?


Pri makrojih moras biti previden. Tvoj makro bi za CUBE(2+5) izracunal 2+5*2+5*2+5 = 2+10+10+5 = 27, namesto 7*7*7

Nekako tako:
#define CUBE(a) (a)*(a)*(a)

Pa se tu bo trikrat racunal a (kaj ce je a zapleten).

Isotropic ::

kompajlaj z intel compilerjem in agresivnimi optimizacijami imo.
kaj pa delas sploh, da rabis met tako hitro izvajanje?

pablic ::

kot je rekel loki uporabljal optimizacije

MrBrdo ::

Mislim da lahko v compilerju vklopis tudi SSE in MMX optimizacije, nisem pa ziher. Ce lahko ti zna kaj pohitriti.
MrBrdo

srus ::

Z uporabo asemblerja ali različnih prevajalnikov ne boš pridobil ničesar. Če ti operacij ne uspe paralerizirati in jih pametno razporediti po večih jedrih je edina alternativa kot je bilo že omenjeno zgoraj uporaba GPU in CUDA.

Isotropic ::

z intelovim prevajalnikom dobis 20-30% glede na ms, gcc recimo.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Matematika - pomoč (strani: 1 2 3 )

Oddelek: Šola
10426778 (23353) daisy22
»

Strassenovo množenje matrik

Oddelek: Programiranje
102171 (1912) eXoo
»

[C++] Shift left (strani: 1 2 )

Oddelek: Programiranje
663531 (3034) Thomas
»

Kvadriranje matrike

Oddelek: Znanost in tehnologija
276143 (5704) Thomas
»

Išče se hiter algoritem za izračun ene čudne matrične operacije.

Oddelek: Znanost in tehnologija
172195 (1686) Thomas

Več podobnih tem