🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.asm
Article #2607

Re: [1/3 NTG] C - Optymalizacje wstawkami

#2607
From: Bogdan (bogdro)
Date: Sat, 08 Jun 2019 21:26
178 lines
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-mail
References: <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