Article View: pl.comp.lang.asm
Article #2607Re: [1/3 NTG] C - Optymalizacje wstawkami
From: Bogdan (bogdro)
Date: Sat, 08 Jun 2019 21:26
Date: Sat, 08 Jun 2019 21:26
178 lines
6430 bytes
6430 bytes
W dniu 06.06.2019 o 11:27, DMR pisze:
> W wolnej chwili zmajstrowałem sobie prostą "biblioteczkę" z podstawowymi funkcjami matematycznymi. Posłużyłem się przy tym "gotowcami" zamieszczonymi na stronie: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
>
> Sqrt liczy się tylko symbolicznie szybciej niż sqrt z biblioteki math.h, pozostałe funkcje są szybsze od 2x wzwyż.
>
> Za Chiny nie mogę rozkminić tych literek między dwukropkami, ale wprowadziłem pewne korekty, per analogiam - i (chyba) działa... ;-)
Witamy.
Jako źródła polecam:
- http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
- podręcznik do GCC, np. http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/,
sekcje 5.34 i 5.35, czy też
https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Using-Assembly-Language-with-C.html#Using-Assembly-Language-with-C
Generalnie składnia to
asm ( "statements" : output_registers : input_registers :
clobbered_registers);
Clobber oznacza rejestry "przypadkowo" psute (jako efekt uboczny)
przez dany blok czy instrukcję.
Mistrzem w tym nie jestem, ale może coś zgadnę (składnia trochę
"kaleczy oczy" ;) ). Także w nierozumieniu tej składni nie jesteś sam :).
Zawsze możesz też przekopać pliki nagłówkowe glibc pod kątem
występowania instrukcji koprocesora. Poszukałem po "fsqrt" i znalazłem
/usr/include/bits/mathinline.h.
> W przypadku "jednoargumentowych" wyrażeń sugerowana jest składnia:
>
> asm ("foo" : "=&t" (a) : "f" (b));
Wyjście = zmienna "a", early-clobber, pobranie z st(0)
(https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Machine-Constraints.html#Machine-Constraints).
Wejście = zmienna "b", float (por. ta sama strona).
> Przy okazji testów szybkości zauważyłem jednak, że jeśli w ten sposób zakoduję funkcje Sin() i Cos(), to w przypadku wywołania w kodzie programu:
>
> sin = Sin(a);
> cos = Cos(a);
>
> poprawnie liczy się kosinus, ale w przypadku sinusa wychodzą jakieś głupoty.
> Wywołanie typu:
>
> tan = Sin(a) / Cos(a)
>
> w ogóle się wywala, a przecież mam tego używać...
>
> Poprzez analogię do przykładu z fsincos i fyl2xp1 do zmieniłem "f" na "0" i wywaliłem ampersanda sprzed t:
>
> asm ("foo" : "=t" (a) : "0" (b));
>
>
> No i teraz wszystko gra!
>
> A dlaczego? Nie mam pojęcia... ;-)
Early-clobber mogło być niepotrzebne.
Wyjście jest zapisane do zmiennej "a" - OK.
Co do "0" - cytat z
https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Extended-Asm.html#Extended-Asm:
Input constraints can also be digits (for example, "0"). This
indicates that the specified input must be in the same place as the
output constraint at the (zero-based) index in the output constraint
list.
Czyli parametr ma być w tym samym miejscu, gdzie pierwszy parametr
wyjściowy. W skrócie: wkładasz wartość do st(0) i wyciągasz też z
st(0). To pewnie pomogło.
Może
asm ("foo" : "=t" (a) : "t" (b));
też by zadziałało.
> //------------------------------------------------------------------------------
> inline double Sqrt(double x)
> {
> double s;
>
> asm ("fsqrt" : "=t" (s) : "0" (x));
>
> return s;
> }
> //------------------------------------------------------------------------------
> inline double Sin(double a)
> {
> double s;
>
> asm ("fsin" : "=t" (s) : "0" (a));
>
> return s;
> }
> //------------------------------------------------------------------------------
> inline double Cos(double a)
> {
> double c;
>
> asm ("fcos" : "=t" (c) : "0" (a));
>
> return c;
> }
Trzy razy odczyt i zapis z st(0) - wygląda dobrze.
> //------------------------------------------------------------------------------
> inline void SinCos(double a, double *sin, double *cos)
> {
> double s, c;
>
> asm ("fsincos" : "=t" (c), "=u" (s) : "0" (a));
>
> *sin = s;
> *cos = c;
> }
> //------------------------------------------------------------------------------
> inline double Tan(double a)
> {
> double t, o;
>
> asm ("fptan" : "=t" (o), "=u" (t) : "0" (a));
>
> return t;
> }
Dwa razy parametr w st(0), a wynik z st(0) i st(1).
W drugim przypadku odrzucamy st(0) (zawierające wartość 1). Tak się
też zastanawiam, czy st(7) nie powinno być na clobber list, sądząc po
opisie działania instrukcji.
> //------------------------------------------------------------------------------
> inline double ATan(double y, double x)
> {
> double a;
>
> asm ("fpatan" : "=t" (a) : "0" (x), "u" (y) : "st(1)");
>
> return a;
> }
> //------------------------------------------------------------------------------
>
Parametry w st(0) - x - i w st(1) - y, a wynik z st(0) do zmiennej "a".
Tutaj też się zastanawiam, czy to raczej st(7) nie powinno być na
clobber list zamiast st(1).
To działa w sensie składniowym? Clobber nie powinien mieć procenta -
%st(1)? Czy może przełączyłeś na składnię intel?
--
Pozdrawiam/Regards - Bogdan (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux): http://bogdro.evai.pl
Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.Xiph.org www.TorProject.org Soft(EN): http://bogdro.evai.pl/soft
Technical Details
Message-ID:
<5cfc27fd$0$541$65785112@news.neostrada.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-02.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mailReferences:
<30292520-12bd-49f0-b5ce-39c9af378a4c@googlegroups.com> <55cb70ec-3acf-43dd-ae35-5821e4c2d51d@googlegroups.com>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-02.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail Subject: Re: [1/3 NTG] C - Optymalizacje wstawkami Newsgroups: pl.comp.lang.asm References: <30292520-12bd-49f0-b5ce-39c9af378a4c@googlegroups.com> <55cb70ec-3acf-43dd-ae35-5821e4c2d51d@googlegroups.com> From: "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> Openpgp: preference=signencrypt Date: Sat, 8 Jun 2019 23:26:20 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 In-Reply-To: <55cb70ec-3acf-43dd-ae35-5821e4c2d51d@googlegroups.com> Lines: 178 Message-ID: <5cfc27fd$0$541$65785112@news.neostrada.pl> Organization: Telekomunikacja Polska NNTP-Posting-Host: 89.64.40.239 X-Trace: 1560029182 unt-rea-a-02.news.neostrada.pl 541 89.64.40.239:22438 X-Complaints-To: abuse@news.neostrada.pl Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit