<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">It happened very accidentally.  Since venv is used,</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">many paths in the interpreter is changed.  So how memory</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">is used are changed.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Let's reproduce the accident.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default"><div class="gmail_default"><font face="arial, helvetica, sans-serif">$ cat m2.py</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">import pickle, sys</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">LIST = pickle.dumps([[0]*10 for _ in range(10)], pickle.HIGHEST_PROTOCOL)</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">N = 1000</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">z = [[0]*10 for _ in range(N)]</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">if '-c' in sys.argv:</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    sys._debugmallocstats()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    sys.exit()</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">for _ in range(100000):</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif">    pickle.loads(LIST)</font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><br></font></div><div class="gmail_default"><font face="arial, helvetica, sans-serif"><div class="gmail_default">$ /usr/bin/time python3 m2.py</div><div class="gmail_default">0.42user 0.00system 0:00.43elapsed 99%CPU (0avgtext+0avgdata 9100maxresident)k</div><div class="gmail_default">0inputs+0outputs (0major+1139minor)pagefaults 0swaps</div><div class="gmail_default"><br></div><div class="gmail_default">There are only 1139 faults.  It is less than 100000.</div><div class="gmail_default"><br></div><div class="gmail_default">$ /usr/bin/time python3 m2.py -c<br></div><div class="gmail_default">...</div><div class="gmail_default">14 unused pools * 4096 bytes       =               57,344<br></div></font></div></div><div class="gmail_default"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">...</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">adjust N im m2.py until it shows "0 unused pools".</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">In my case, N=1390.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><div class="gmail_default">$ /usr/bin/time python3 m2.py</div><div class="gmail_default">0.51user 0.33system 0:00.85elapsed 99%CPU (0avgtext+0avgdata 9140maxresident)k</div><div class="gmail_default">0inputs+0outputs (0major+201149minor)pagefaults 0swaps</div><div class="gmail_default"><br></div><div class="gmail_default">200000 faults!</div><div class="gmail_default">It seems two page fault / loop.  (2 pools are used and returned).</div></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 27, 2019 at 7:51 PM Victor Stinner <<a href="mailto:vstinner@redhat.com">vstinner@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Sorry, I didn't get a coffee yet: more *often* in a venv.<br>
<br>
Le mer. 27 févr. 2019 à 11:32, Victor Stinner <<a href="mailto:vstinner@redhat.com" target="_blank">vstinner@redhat.com</a>> a écrit :<br>
><br>
> Any idea why Python calls mmap+munmap more even in a venv?<br>
><br>
> Victor<br>
><br>
> Le mer. 27 févr. 2019 à 10:00, INADA Naoki <<a href="mailto:songofacandy@gmail.com" target="_blank">songofacandy@gmail.com</a>> a écrit :<br>
> ><br>
> > ><br>
> > > > Ah, another interesting point, this huge slowdown happens only when bm_pickle.py<br>
> > > > is executed through pyperformance.  When run it directly, slowdown is<br>
> > > > not so large.<br>
> > ><br>
> > > pyperformance runs benchmarks in a virtual environment. I don't know<br>
> > > if it has any impact on bm_pickle.<br>
> > ><br>
> > > Most pyperformance can be run outside a virtual env if required<br>
> > > modules are installed on the system. (bm_pickle only requires the<br>
> > > stdlib and perf.)<br>
> > ><br>
> ><br>
> > Bingo!<br>
> ><br>
> > Without venv:<br>
> ><br>
> > unpickle: Mean +- std dev: 26.9 us +- 0.0 us<br>
> > % time     seconds  usecs/call     calls    errors syscall<br>
> > ------ ----------- ----------- --------- --------- ----------------<br>
> >  28.78    0.000438           0      1440           read<br>
> >  27.33    0.000416           1       440        25 stat<br>
> >   9.72    0.000148           1       144           mmap<br>
> > ...<br>
> >   0.79    0.000012           1        11           munmap<br>
> ><br>
> > With venv:<br>
> ><br>
> > % time     seconds  usecs/call     calls    errors syscall<br>
> > ------ ----------- ----------- --------- --------- ----------------<br>
> >  57.12    0.099023           2     61471           munmap<br>
> >  41.87    0.072580           1     61618           mmap<br>
> >   0.23    0.000395           1       465        27 stat<br>
> ><br>
> > unpickle and unpickle_list creates massive same-sized objects, then all objects are<br>
> > removed.  If all pools in the arena is freed, munmap is called.<br>
> ><br>
> > I think we should save some arenas to reuse.  On recent Linux,<br>
> > we may be able to use MADV_FREE instead of munmap.<br>
> ><br>
><br>
><br>
> --<br>
> Night gathers, and now my watch begins. It shall not end until my death.<br>
<br>
<br>
<br>
-- <br>
Night gathers, and now my watch begins. It shall not end until my death.<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature">INADA Naoki  <<a href="mailto:songofacandy@gmail.com" target="_blank">songofacandy@gmail.com</a>></div>