🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.c
Article #309968

Jak zoptymalizować modyfikację komórki pamięci z carry?

#309968
From: Borneq
Date: Mon, 11 Nov 2019 18:37
58 lines
3134 bytes
Sercem procedury mnożenia zwykłego(mpn_mul_basecase) w GMP jest 
mpir_addmul_1
MPIR jest wysoce zoptymalizowane i działa pod Visualem C++. W MPIR są 
dostarczone kody asemblerowe pod różne procesory.
Nie za bardzo lubię asemblera, trudno konfigurowalne, różne dla 
procesora, kompilatora, trybut 32/64 bitów itd.
I dla dzisiejszych procesorów trudno coś ręcznie zoptymalizować w 
assemblerze, zwłaszcza gdy nie ma SSE.
Jednak mpir_addmul_1 w assemblerze jest 2 razy szybszy!
W C:(usuwając nieistotne)
mp_limb_t addmul_1(mp_ptr rp, mp_srcptr up, mp_size_t n, mp_limb_t vl)
{
	mp_limb_t ul, cl, hpl, lpl, rl;
	cl = 0;
	do
	{
		ul = *up++;
		umul_ppmm(hpl, lpl, ul, vl);
		lpl += cl;
		cl = (lpl < cl) + hpl;
		rl = *rp;
		lpl = rl + lpl;
		cl += lpl < rl;
		*rp++ = lpl;
	} while (--n != 0);
	return cl;
}

gdzie długie mnożenie jest w umul_ppmm:
#    define umul_ppmm(xh, xl, m0, m1)       \
      do  {                                  \
            xl = _umul128( (m0), (m1), &xh); \
          } while (0)

a dla GCC po prostu:
          do  {                                  \
         mp_limb_double_t w = (mp_limb_double_t)x * y; \
         r_lo = (mp_limb_t)w;                             \
         r_hi = (mp_limb_t)(w >> GMP_LIMB_BITS);                     \
     } while (0)
bo ma tam typ 128 bitowy

JEDNAK
spowolnienie nie jest związane z tym mnożeniem, w asm jest podobnie choć 
używa mulx zamiast mul, który nie ustawia flag, w VC++ też można użyć 
zamiast _umul128 w razie konieczności.
JEDNAK
związane jest z tym że dostęp do pamięci jest wolniejszy niż do 
rejestrów, i trzeba dostać się dwukrotnie:
rl = *rp
*rp++
Można od razu przy jednym dostępie zwiększać o lpl, jednak dochodzi 
Carry. Carry można ustawić przez rzutowanie wyniku porównania na liczbę, 
wtedy nie generuje skoków.
PYTANIE: czy można modyfikować tylko rejestry, a potem zwiększyć tylko 
odpowiednio *rp ? Ale wtedy jak odczytać carry? W assemblerze można, 
natomiast tutaj jedyną metodą jest sprawdzenie czy wynik jest mniejszy 
niż którykolwiek składnik sumy (koniecznie dwóch a nie większej ilości)
Technical Details
Message-ID: <5dc9aa52$0$17343$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-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail

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-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail
Newsgroups: pl.comp.lang.c
X-Mozilla-News-Host: news://news.neostrada.pl:119
From: Borneq <borneq@antyspam.hidden.p>
Subject: Jak
 zoptymalizować modyfikację komórki pamięci z
 carry?
Date: Mon, 11 Nov 2019 19:37:06 +0100
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.9.1
MIME-Version: 1.0
Lines: 58
Message-ID: <5dc9aa52$0$17343$65785112@news.neostrada.pl>
Organization: Telekomunikacja Polska
NNTP-Posting-Host: 91.239.205.59
X-Trace: 1573497427 unt-rea-a-01.news.neostrada.pl 17343 91.239.205.59:50820
X-Complaints-To: abuse@news.neostrada.pl
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit