Commit e48751e2 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: increase page size to 8K

Tcmalloc uses 8K, 32K and 64K pages, and in custom setups 256K pages.
Only Chromium uses 4K pages today (in "slow but small" configuration).
The general tendency is to increase page size, because it reduces
metadata size and DTLB pressure.
This change reduces GC pause by ~10% and slightly improves other metrics.

json-1
allocated                 8037492      8038689      +0.01%
allocs                     105762       105573      -0.18%
cputime                 158400000    155800000      -1.64%
gc-pause-one              4412234      4135702      -6.27%
gc-pause-total            2647340      2398707      -9.39%
rss                      54923264     54525952      -0.72%
sys-gc                    3952624      3928048      -0.62%
sys-heap                 46399488     46006272      -0.85%
sys-other                 5597504      5290304      -5.49%
sys-stack                  393216       393216      +0.00%
sys-total                56342832     55617840      -1.29%
time                    158478890    156046916      -1.53%
virtual-mem             256548864    256593920      +0.02%

garbage-1
allocated                 2991113      2986259      -0.16%
allocs                      62844        62652      -0.31%
cputime                  16330000     15860000      -2.88%
gc-pause-one            789108229    725555211      -8.05%
gc-pause-total            3945541      3627776      -8.05%
rss                    1143660544   1132253184      -1.00%
sys-gc                   65609600     65806208      +0.30%
sys-heap               1032388608   1035599872      +0.31%
sys-other                37501632     22777664     -39.26%
sys-stack                 8650752      8781824      +1.52%
sys-total              1144150592   1132965568      -0.98%
time                     16364602     15891994      -2.89%
virtual-mem            1327296512   1313746944      -1.02%

This is the exact reincarnation of already LGTMed:
https://golang.org/cl/45770044
which must not break darwin/freebsd after:
https://golang.org/cl/56630043
TBR=iant

LGTM=khr, iant
R=iant, khr
CC=golang-codereviews
https://golang.org/cl/58230043
parent ae8251b0
......@@ -19,6 +19,7 @@ package runtime
// Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K.
#pragma dataflag NOPTR
MHeap runtime·mheap;
MStats mstats;
int32 runtime·checking;
......@@ -417,7 +418,10 @@ runtime·purgecachedstats(MCache *c)
}
}
uintptr runtime·sizeof_C_MStats = sizeof(MStats);
// Size of the trailing by_size array differs between Go and C,
// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
// sizeof_C_MStats is what C thinks about size of Go struct.
uintptr runtime·sizeof_C_MStats = sizeof(MStats) - (NumSizeClasses - 61) * sizeof(mstats.by_size[0]);
#define MaxArena32 (2U<<30)
......
......@@ -90,7 +90,7 @@ typedef struct GCStats GCStats;
enum
{
PageShift = 12,
PageShift = 13,
PageSize = 1<<PageShift,
PageMask = PageSize - 1,
};
......@@ -103,7 +103,7 @@ enum
// size classes. NumSizeClasses is that number. It's needed here
// because there are static arrays of this length; when msize runs its
// size choosing algorithm it double-checks that NumSizeClasses agrees.
NumSizeClasses = 61,
NumSizeClasses = 67,
// Tunable constants.
MaxSmallSize = 32<<10,
......@@ -259,7 +259,7 @@ struct MStats
} by_size[NumSizeClasses];
};
#define mstats runtime·memStats /* name shared with Go */
#define mstats runtime·memStats
extern MStats mstats;
// Size classes. Computed and initialized by InitSizes.
......
......@@ -60,9 +60,8 @@ type MemStats struct {
var sizeof_C_MStats uintptr // filled in by malloc.goc
var memStats MemStats
func init() {
var memStats MemStats
if sizeof_C_MStats != unsafe.Sizeof(memStats) {
println(sizeof_C_MStats, unsafe.Sizeof(memStats))
panic("MStats vs MemStatsType size mismatch")
......
......@@ -25,6 +25,10 @@ enum {
wordsPerBitmapWord = sizeof(void*)*8/4,
bitShift = sizeof(void*)*8/4,
WorkbufSize = 16*1024,
RootBlockSize = 4*1024,
FinBlockSize = 4*1024,
handoffThreshold = 4,
IntermediateBufferCapacity = 64,
......@@ -154,11 +158,10 @@ struct Obj
uintptr ti; // type info
};
// The size of Workbuf is N*PageSize.
typedef struct Workbuf Workbuf;
struct Workbuf
{
#define SIZE (2*PageSize-sizeof(LFNode)-sizeof(uintptr))
#define SIZE (WorkbufSize-sizeof(LFNode)-sizeof(uintptr))
LFNode node; // must be first
uintptr nobj;
Obj obj[SIZE/sizeof(Obj) - 1];
......@@ -737,7 +740,7 @@ scanblock(Workbuf *wbuf, bool keepworking)
ChanType *chantype;
Obj *wp;
if(sizeof(Workbuf) % PageSize != 0)
if(sizeof(Workbuf) % WorkbufSize != 0)
runtime·throw("scanblock: size of Workbuf is suboptimal");
// Memory arena parameters.
......@@ -1601,8 +1604,8 @@ runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType
runtime·lock(&finlock);
if(finq == nil || finq->cnt == finq->cap) {
if(finc == nil) {
finc = runtime·persistentalloc(PageSize, 0, &mstats.gc_sys);
finc->cap = (PageSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
finc = runtime·persistentalloc(FinBlockSize, 0, &mstats.gc_sys);
finc->cap = (FinBlockSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
finc->alllink = allfin;
allfin = finc;
}
......@@ -2233,6 +2236,8 @@ gc(struct gc_args *args)
runtime·MProf_GC();
}
extern uintptr runtime·sizeof_C_MStats;
void
runtime·ReadMemStats(MStats *stats)
{
......@@ -2244,7 +2249,9 @@ runtime·ReadMemStats(MStats *stats)
m->gcing = 1;
runtime·stoptheworld();
updatememstats(nil);
*stats = mstats;
// Size of the trailing by_size array differs between Go and C,
// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
runtime·memcopy(runtime·sizeof_C_MStats, stats, &mstats);
m->gcing = 0;
m->locks++;
runtime·semrelease(&runtime·worldsema);
......
......@@ -34,6 +34,11 @@ package net
#define READY ((G*)1)
#define WAIT ((G*)2)
enum
{
PollBlockSize = 4*1024,
};
struct PollDesc
{
PollDesc* link; // in pollcache, protected by pollcache.Lock
......@@ -422,7 +427,7 @@ allocPollDesc(void)
runtime·lock(&pollcache);
if(pollcache.first == nil) {
n = PageSize/sizeof(*pd);
n = PollBlockSize/sizeof(*pd);
if(n == 0)
n = 1;
// Must be in non-GC memory because can be referenced
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment