Skip to content
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

Speed up counting of bits in allocator #104968

Merged
merged 2 commits into from
Oct 2, 2021
Merged

Speed up counting of bits in allocator #104968

merged 2 commits into from
Oct 2, 2021

Conversation

twpayne
Copy link
Contributor

@twpayne twpayne commented Sep 13, 2021

What type of PR is this?

/kind cleanup

What this PR does / why we need it:

This PR tidies up counting of bits in pkg/registry/core/service/allocator.

Switching from using math/big.Int.Bytes to math/big.Int.Bits has two effects:

  • It removes an allocation (there is no longer a need for an intermediate []byte).
  • It allows the bits to be counted 64 at a time instead of 8 at a time.

Which issue(s) this PR fixes:

NONE

Special notes for your reviewer:

Does this PR introduce a user-facing change?

NONE

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Sep 13, 2021
@k8s-ci-robot
Copy link
Contributor

@twpayne: This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot
Copy link
Contributor

Welcome @twpayne!

It looks like this is your first PR to kubernetes/kubernetes 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/kubernetes has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot
Copy link
Contributor

Hi @twpayne. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Sep 13, 2021
@twpayne
Copy link
Contributor Author

twpayne commented Sep 13, 2021

/assign @smarterclayton

@twpayne
Copy link
Contributor Author

twpayne commented Sep 13, 2021

/unassign @smarterclayton

@aojea
Copy link
Member

aojea commented Sep 13, 2021

we should have some benchmarks demonstrating this

@twpayne
Copy link
Contributor Author

twpayne commented Oct 1, 2021

we should have some benchmarks demonstrating this

The code that this replaces performs the following steps:

  1. Allocates a []byte for the words in n (a math/big.Int).
  2. Calls this function to copy n's words (effectively a []unit64) into a []byte.
  3. Iterates over each byte, counting the set bits 8 at a time.

The replacement code in this PR performs the following steps:

  1. Iterates over n's words counting the set bits 64 at a time.

Is it necessary to demonstrate that the replacement code is faster than the replaced code with a benchmark?

@aojea
Copy link
Member

aojea commented Oct 1, 2021

Is it necessary to demonstrate that the replacement code is faster than the replaced code with a benchmark?

yep

Benchmark:

goos: linux
goarch: amd64
pkg: k8s.io/kubernetes/pkg/registry/core/service/allocator
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz

Before:

BenchmarkCountBits-8     9459236               140.4 ns/op

After:

BenchmarkCountBits-8    140667842                9.541 ns/op
@twpayne
Copy link
Contributor Author

twpayne commented Oct 1, 2021

OK, benchmark:

Before:

goos: linux
goarch: amd64
pkg: k8s.io/kubernetes/pkg/registry/core/service/allocator
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
BenchmarkCountBits-8     9459236               140.4 ns/op

After:

goos: linux
goarch: amd64
pkg: k8s.io/kubernetes/pkg/registry/core/service/allocator
cpu: Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
BenchmarkCountBits-8    140667842                9.541 ns/op

@twpayne
Copy link
Contributor Author

twpayne commented Oct 1, 2021

/assign @smarterclayton

@aojea
Copy link
Member

aojea commented Oct 1, 2021

/ok-to-test
/lgtm
/assign @thockin
naive question, can there be some issues in 32 bits architectures?

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Oct 1, 2021
@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 1, 2021
@twpayne
Copy link
Contributor Author

twpayne commented Oct 1, 2021

naive question, can there be some issues in 32 bits architectures?

On 32-bit machines math/big.Ints use []uint32s instead of []uint64, however the math/bits.OnesCount64 will still correctly count the bits in a uint32 as the upper bits will be zero when Go converts the uint32 to a uint64.

Note that math/bits.OnesCount64 is already used by Kubernetes.

Copy link
Member

@thockin thockin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

/lgtm
/approve

@@ -24,8 +24,8 @@ import (
// countBits returns the number of set bits in n
func countBits(n *big.Int) int {
var count int = 0
for _, b := range n.Bytes() {
count += bits.OnesCount8(uint8(b))
for _, w := range n.Bits() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs for math/big.Word say "A Word represents a single digit of a multi-precision unsigned integer" which is certainly not explaining very much.

The docs for Bits() say "Bits is intended to support implementation of missing low-level Int functionality outside this package; it should be avoided otherwise." I guess this counts as "missing low-level Int functionality".

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: aanm, thockin, twpayne

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Oct 1, 2021
@aojea
Copy link
Member

aojea commented Oct 1, 2021

/sig network
as the allocator belong to services???

@k8s-ci-robot k8s-ci-robot added sig/network Categorizes an issue or PR as relevant to SIG Network. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Oct 1, 2021
@k8s-ci-robot k8s-ci-robot merged commit 0ac956f into kubernetes:master Oct 2, 2021
@k8s-ci-robot k8s-ci-robot added this to the v1.23 milestone Oct 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. release-note-none Denotes a PR that doesn't merit a release note. sig/network Categorizes an issue or PR as relevant to SIG Network. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants