New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: add a minimum allocation field to bound accounts #31191

Open
wants to merge 1 commit into
base: master
from

Conversation

Projects
None yet
3 participants
@changangela
Collaborator

changangela commented Oct 10, 2018

This change adds on to the work done in #30924.

Currently, a bound account will reserve a small buffer of up to poolAllocationSize. When the account grows, this buffer is first used up before additional memory is reserved from the monitor. When the account shrinks, memory is released from this buffer to a minimum of poolAllocationSize. We want to be able to dynamically set a minimum allocated value in order to amortize the cost of constantly growing and shrinking a account. This field is different from poolAllocationSize in the
following ways:

  • there is overhead introduced by a call to releaseBytes and if we are always "shrinking" the reserved buffer to a constant size of poolAllocationSize, this overhead becomes quite prominent. Instead, if we establish a minimum value for allocated = reserved + used, then the call to releaseBytes becomes much less frequent.
  • in the case where we "grow" the account to above the minAllocated size, then we don't want the account to buffer up another chunk of minAllocated, instead it will reserve memory in conservative poolAllocationSize blocks.

This PR mainly adds the necessary documentation and comments that was not present in #30924.

Release note: None

@changangela changangela requested a review from knz Oct 10, 2018

@cockroach-teamcity

This comment has been minimized.

Show comment
Hide comment
@cockroach-teamcity

cockroach-teamcity Oct 10, 2018

Member

This change is Reviewable

Member

cockroach-teamcity commented Oct 10, 2018

This change is Reviewable

@changangela

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained


pkg/util/mon/bytes_usage.go, line 661 at r1 (raw file):

// reserveBytes().
func (mm *BytesMonitor) releaseBytes(ctx context.Context, sz int64) {
	if sz == 0 {

Prior to #31191, adding this condition sped up the MergeJoinerBenchmark by ~50%. However, the same problem could be fixed by using the condition released > 0 instead of released >= 0. I originally added this check in as a precaution for users without thinking of the overhead. Since it doesn't provide any additional value specific to the current bytes_usage functions, I've removed it.

@changangela

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained


pkg/util/mon/bytes_usage.go, line 454 at r2 (raw file):

	// minAllocated is a minimum allocated bytes size that the account reach
	// before being able to release bytes.
	minAllocated int64

Working on investigating the memory usage concerns with adding this extra field.

@knz

Thanks for the additional insight. Please have a look at my remaining comment below.

With this additional insight I must say I am surprised by this change -- it looks to me that you could have achieved the same result in the distsql processor as follows:

  1. request the minallocated bytes via a regular (unchanged) BoundAccount
  2. create a sub-monitor (not account) in the processor with the boundaccount created at step 1 as reserved bytes
  3. do memory accounting in the processor using the sub-monitor

I think this achieves the same, with a similar performance profile, and without changes to the mon package. What do you think?

Reviewed 1 of 1 files at r2.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained


pkg/util/mon/bytes_usage.go, line 447 at r2 (raw file):

// additional memory and parceling it out (see BoundAccount.reserved). The
// amount of additional memory is determined by the value of
// BoundAccount.minAllocated. By default, BoundAccount.minAllocated is set to 0.

What is the relationship between reserved, mentioned in the previous sentence, and minAllocated introduced here?

The phrasing currently reads like both fields are doing the same thing.

What does minAllocated add which is not already comprised in reserved? (Other way around: why is reserved not sufficient to set a minimum?)

@changangela

Originally, I think we were going for a more general approach that wasn't specific to the distsql processor, but I think that using this sub-monitor approach makes sense to solve this problem makes sense. I'm thinking that using the sub-monitor would introduce more overhead than this approach because it will still have to talk back and forth with the BoundAccount to manipulate values. I'd be interested in trying it out and benchmarking it.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained

@changangela changangela requested a review from cockroachdb/build-prs as a code owner Oct 10, 2018

@changangela

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained


pkg/util/mon/bytes_usage.go, line 447 at r2 (raw file):

Previously, knz (kena) wrote…

What is the relationship between reserved, mentioned in the previous sentence, and minAllocated introduced here?

The phrasing currently reads like both fields are doing the same thing.

What does minAllocated add which is not already comprised in reserved? (Other way around: why is reserved not sufficient to set a minimum?)

Done.

sql: add a minimum allocation field to bound accounts
Currently, a bound account will reserve a small buffer of up to `poolAllocationSize`. When the account grows, this buffer is first used up before additional memory is reserved from the monitor. When the account shrinks, memory is released from this buffer to a minimum of `poolAllocationSize`. We want to be able to dynamically set a minimum allocated value in order to amortize the cost of constantly growing and shrinking a account. This field is different from `poolAllocationSize` in the
following ways:

- there is overhead introduced by a call to `releaseBytes` and if we are always "shrinking" the reserved buffer to a constant size, this overhead becomes quite prominent. Instead, if we establish a minimum value for reserved + used, then the call to `releaseBytes` becomes much less frequent.
- in the case where we "grow" the account to above the `minAllocated` size, then we don't want the account to buffer up another chunk of `minAllocated`, instead it will reserve memory in conservative `poolAllocationSize` blocks.

Release note: None

craig bot pushed a commit that referenced this pull request Oct 11, 2018

Merge #31216 #31219
31216: sql: add merge joiner benchmark and bytes usage optimization r=changangela a=changangela

Reverted #30924 for now to compare different approaches (discussed in #31191). This PR is mainly for adding some merge joiner benchmarks as well a small change in `BoundAccount.Shrink()` that significantly improves the merge joiner performance. This way, we can safely backport this change.

MergeJoinerBenchmark against `release-2.1`:

```
name                           old time/op    new time/op    delta
MergeJoiner/InputSize=0-8        4.31µs ±10%    4.33µs ±15%      ~     (p=0.968 n=10+9)
MergeJoiner/InputSize=4-8        8.34µs ± 3%    8.10µs ± 4%      ~     (p=0.074 n=8+9)
MergeJoiner/InputSize=16-8       16.3µs ± 2%    11.1µs ± 5%   -31.87%  (p=0.000 n=9+9)
MergeJoiner/InputSize=256-8       190µs ± 2%      85µs ± 2%   -55.04%  (p=0.000 n=10+8)
MergeJoiner/InputSize=4096-8     2.96ms ± 2%    1.28ms ± 2%   -56.86%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8    49.0ms ± 5%    20.6ms ± 1%   -57.88%  (p=0.000 n=10+10)

name                           old alloc/op   new alloc/op   delta
MergeJoiner/InputSize=0-8        6.42kB ± 0%    6.65kB ± 0%    +3.49%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8        9.50kB ± 0%    9.72kB ± 0%    +2.36%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8       9.50kB ± 0%    9.72kB ± 0%    +2.36%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8      32.5kB ± 0%    32.8kB ± 0%    +0.69%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8      401kB ± 0%     401kB ± 0%    +0.06%  (p=0.000 n=9+10)
MergeJoiner/InputSize=65536-8    6.30MB ± 0%    6.30MB ± 0%    +0.00%  (p=0.000 n=9+10)

name                           old allocs/op  new allocs/op  delta
MergeJoiner/InputSize=0-8          14.0 ± 0%      15.0 ± 0%    +7.14%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8          16.0 ± 0%      17.0 ± 0%    +6.25%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8         16.0 ± 0%      17.0 ± 0%    +6.25%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8        46.0 ± 0%      47.0 ± 0%    +2.17%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8        526 ± 0%       527 ± 0%    +0.19%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8     8.21k ± 0%     8.21k ± 0%    +0.01%  (p=0.000 n=10+10)

name                           old speed      new speed      delta
MergeJoiner/InputSize=4-8      7.67MB/s ± 3%  7.91MB/s ± 4%      ~     (p=0.070 n=8+9)
MergeJoiner/InputSize=16-8     15.7MB/s ± 2%  23.0MB/s ± 5%   +46.89%  (p=0.000 n=9+9)
MergeJoiner/InputSize=256-8    21.6MB/s ± 2%  48.0MB/s ± 2%  +122.41%  (p=0.000 n=10+8)
MergeJoiner/InputSize=4096-8   22.1MB/s ± 2%  51.3MB/s ± 2%  +131.81%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8  21.4MB/s ± 5%  50.8MB/s ± 1%  +137.16%  (p=0.000 n=10+10)
```

MergeJoinerBenchmark compared with `master` (`master` already has this exact optimization, we want to ensure that the performance did not deteriorate)
```
name                                          old time/op    new time/op    delta
MergeJoiner/InputSize=0-8                       4.61µs ± 9%    4.45µs ± 5%     ~     (p=0.060 n=10+10)
MergeJoiner/InputSize=4-8                       8.34µs ± 6%    8.00µs ±10%   -4.09%  (p=0.037 n=9+10)
MergeJoiner/InputSize=16-8                      11.6µs ± 4%    11.4µs ± 5%     ~     (p=0.123 n=10+10)
MergeJoiner/InputSize=256-8                     88.3µs ± 3%    89.8µs ± 6%     ~     (p=0.258 n=9+9)
MergeJoiner/InputSize=4096-8                    1.33ms ± 4%    1.27ms ± 5%   -4.67%  (p=0.001 n=9+10)
MergeJoiner/InputSize=65536-8                   22.4ms ± 6%    21.3ms ±10%     ~     (p=0.052 n=10+10)
MergeJoiner/OneSideRepeatInputSize=0-8          4.57µs ±15%    4.38µs ± 6%     ~     (p=0.353 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8          7.71µs ±10%    7.71µs ± 4%     ~     (p=0.549 n=10+9)
MergeJoiner/OneSideRepeatInputSize=16-8         11.8µs ±29%    10.5µs ± 6%  -10.77%  (p=0.043 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8        82.8µs ± 4%    80.3µs ± 5%   -2.93%  (p=0.004 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8       1.25ms ± 2%    1.54ms ±13%  +23.09%  (p=0.000 n=9+10)
MergeJoiner/OneSideRepeatInputSize=65536-8      24.2ms ± 3%    26.7ms ± 9%  +10.08%  (p=0.000 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=0-8        4.60µs ±10%    4.36µs ±10%     ~     (p=0.063 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4-8        7.13µs ± 4%    7.62µs ±17%   +6.84%  (p=0.005 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=16-8       8.66µs ±14%    8.24µs ± 3%     ~     (p=0.549 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=256-8      22.1µs ± 5%    23.2µs ± 9%   +5.06%  (p=0.004 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8      219µs ± 4%     240µs ±25%     ~     (p=0.065 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8    1.19ms ± 3%    1.17ms ± 1%   -2.18%  (p=0.001 n=10+9)

name                                          old alloc/op   new alloc/op   delta
MergeJoiner/InputSize=0-8                       6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4-8                       9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/InputSize=16-8                      9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/InputSize=256-8                     32.8kB ± 0%    32.8kB ± 0%   -0.05%  (p=0.000 n=10+10)
MergeJoiner/InputSize=4096-8                     401kB ± 0%     401kB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/InputSize=65536-8                   6.30MB ± 0%    6.30MB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=0-8          6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8          9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=16-8         9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8        42.0kB ± 0%    42.0kB ± 0%   -0.04%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8        751kB ± 0%     751kB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/OneSideRepeatInputSize=65536-8      15.5MB ± 0%    15.5MB ± 0%   -0.00%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=0-8        6.66kB ± 0%    6.65kB ± 0%   -0.24%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4-8        9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=16-8       9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=256-8      9.74kB ± 0%    9.72kB ± 0%   -0.16%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8     14.3kB ± 0%    14.3kB ± 0%   -0.11%  (p=0.000 n=10+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8    38.9kB ± 0%    38.9kB ± 0%   -0.04%  (p=0.000 n=10+10)

name                                          old allocs/op  new allocs/op  delta
MergeJoiner/InputSize=0-8                         15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=4-8                         17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=16-8                        17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=256-8                       47.0 ± 0%      47.0 ± 0%     ~     (all equal)
MergeJoiner/InputSize=4096-8                       527 ± 0%       527 ± 0%     ~     (all equal)
MergeJoiner/InputSize=65536-8                    8.21k ± 0%     8.21k ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=0-8            15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=4-8            17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=16-8           17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=256-8          49.0 ± 0%      49.0 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=4096-8          536 ± 0%       536 ± 0%     ~     (all equal)
MergeJoiner/OneSideRepeatInputSize=65536-8       8.23k ± 0%     8.23k ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=0-8          15.0 ± 0%      15.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=4-8          17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=16-8         17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=256-8        17.0 ± 0%      17.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=4096-8       23.0 ± 0%      23.0 ± 0%     ~     (all equal)
MergeJoiner/BothSidesRepeatInputSize=65536-8      49.0 ± 0%      49.0 ± 0%     ~     (all equal)

name                                          old speed      new speed      delta
MergeJoiner/InputSize=4-8                     7.68MB/s ± 6%  8.02MB/s ± 9%   +4.43%  (p=0.037 n=9+10)
MergeJoiner/InputSize=16-8                    22.2MB/s ± 4%  22.6MB/s ± 5%     ~     (p=0.123 n=10+10)
MergeJoiner/InputSize=256-8                   46.4MB/s ± 3%  45.6MB/s ± 5%     ~     (p=0.231 n=9+9)
MergeJoiner/InputSize=4096-8                  49.2MB/s ± 4%  51.6MB/s ± 5%   +4.93%  (p=0.001 n=9+10)
MergeJoiner/InputSize=65536-8                 46.8MB/s ± 6%  49.3MB/s ± 9%     ~     (p=0.052 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4-8        8.32MB/s ± 9%  8.31MB/s ± 4%     ~     (p=0.549 n=10+9)
MergeJoiner/OneSideRepeatInputSize=16-8       22.1MB/s ±24%  24.3MB/s ± 6%  +10.32%  (p=0.037 n=10+10)
MergeJoiner/OneSideRepeatInputSize=256-8      49.5MB/s ± 4%  51.0MB/s ± 5%   +3.03%  (p=0.003 n=10+10)
MergeJoiner/OneSideRepeatInputSize=4096-8     52.5MB/s ± 2%  42.8MB/s ±12%  -18.43%  (p=0.000 n=9+10)
MergeJoiner/OneSideRepeatInputSize=65536-8    43.3MB/s ± 3%  39.4MB/s ± 9%   -8.94%  (p=0.000 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=4-8      8.98MB/s ± 4%  8.45MB/s ±15%   -5.96%  (p=0.005 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=16-8     29.7MB/s ±13%  31.1MB/s ± 3%     ~     (p=0.549 n=10+9)
MergeJoiner/BothSidesRepeatInputSize=256-8     186MB/s ± 5%   177MB/s ± 8%   -4.73%  (p=0.004 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=4096-8    299MB/s ± 3%   276MB/s ±21%     ~     (p=0.065 n=9+10)
MergeJoiner/BothSidesRepeatInputSize=65536-8   878MB/s ± 3%   898MB/s ± 1%   +2.22%  (p=0.001 n=10+9)
```

31219: kubernetes: Update request-cert image version to include recent fix r=a-robinson a=a-robinson

See cockroachdb/k8s#14

Release note: None

Co-authored-by: changangela <angelachang27@gmail.com>
Co-authored-by: Alex Robinson <alexdwanerobinson@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment