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

cmd/gc: optimize memset idiom #5373

Closed
bradfitz opened this issue Apr 29, 2013 · 17 comments
Closed

cmd/gc: optimize memset idiom #5373

bradfitz opened this issue Apr 29, 2013 · 17 comments

Comments

@bradfitz
Copy link
Contributor

There should be a fast way to zero memory.

When implementing object pools (reusing []byte or []int), for safety the application's
pool allocator needs to zero memory before giving it back out to callers.  Currently Go
can't do it very quickly.
@rsc
Copy link
Contributor

rsc commented May 1, 2013

Comment 1:

It should probably be
for i := range b {
   b[i] = 0
}
and let the compiler optimize it.

@bradfitz
Copy link
Contributor Author

bradfitz commented May 1, 2013

Comment 2:

Ideally, yes.
Rob was talking about this, so I filed a bug.
I'd also want:
for i := range b {
   b[i] = MyStruct{}
}
... to be recognized.

@rsc
Copy link
Contributor

rsc commented May 1, 2013

Comment 3:

Yes, it should work for any zero value.

@cznic
Copy link
Contributor

cznic commented May 3, 2013

Comment 4:

I'd hope for
for i := range b {
   b[i] = 42
}
to be optimized in the same way.

@rsc
Copy link
Contributor

rsc commented Jun 3, 2013

Comment 5:

Labels changed: added go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 6:

Labels changed: added go1.3, removed go1.2maybe.

@robpike
Copy link
Contributor

robpike commented Aug 20, 2013

Comment 7:

Labels changed: removed go1.3.

@rsc
Copy link
Contributor

rsc commented Nov 27, 2013

Comment 8:

Labels changed: added go1.3maybe.

@alberts
Copy link
Contributor

alberts commented Nov 27, 2013

Comment 9:

Had to implement an object pool. Needed this.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 10:

Labels changed: added release-none, removed go1.3maybe.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 11:

Labels changed: added repo-main.

@gopherbot
Copy link

Comment 12 by lk4d4math:

snappy-go now suffer from huge hashtable allocations on each encode. Now bultin
copy(dst, initSlice) works twice faster than loop, but it is still slow like new
allocation.

@davecheney
Copy link
Contributor

Comment 13:

In Go 1.2 we picked up 20-30% for snappy. Can you please provide some more details about
the issue you are seeing.

@gopherbot
Copy link

Comment 14 by lk4d4math:

I am just test some snappy libs and python(just wrapper for C++ implementation) is twice
faster than pure go implementation. I used profiler and see that significant time
spending on allocating empty array of 1<<14 size. So I am tried write memory pool
and request "golang memset" led me here)

@gopherbot
Copy link

Comment 15 by lobais:

Really, a way to zero any type, would be ideal.
If 
    for i := range b {
        b[i] = MyStruct{}
    }
were recognized as a way to zero a slice of `MyStruct`, then
    s := MyStruct{...}
    s = MyStruct{}
should probably also do no allocations (in line 2).
But then, for a struct like
    type MyStruct struct {
        slice []int
    }
there would suddenly be a no-loop way to zero an int-slice.
I don't know what to make of this, other than that zeroing types seems like a natural
thing to do, given Go's great idiom of zeroed types being (transitively) useful.

@josharian
Copy link
Contributor

Comment 16:

memclr only: https://golang.org/cl/137880043
memset requires an efficient runtime memset implementation and a discussion of pattern
length: repeating bytes? repeating words?
As a data point, a pass through the stdlib yields three non-test uses of this memset
idiom:
strings/replace.go NewReplacer
strconv/decimal.go digitZero
httputil/dump.go neverending.Read
All are slices or arrays of bytes.

Owner changed to @josharian.

Status changed to Started.

josharian added a commit to josharian/go that referenced this issue Jan 8, 2015
Recognize loops of the form

for i := range a {
	a[i] = zero
}

in which the evaluation of a is free from side effects.
Replace these loops with calls to memclr.
This occurs in the stdlib in 18 places.

The motivating example is clearing a byte slice:

benchmark                old ns/op     new ns/op     delta
BenchmarkGoMemclr5       3.31          3.26          -1.51%
BenchmarkGoMemclr16      13.7          3.28          -76.06%
BenchmarkGoMemclr64      50.8          4.14          -91.85%
BenchmarkGoMemclr256     157           6.02          -96.17%

Update golang#5373.

Change-Id: I99d3e6f5f268e8c6499b7e661df46403e5eb83e4
josharian added a commit that referenced this issue Jan 9, 2015
Recognize loops of the form

for i := range a {
	a[i] = zero
}

in which the evaluation of a is free from side effects.
Replace these loops with calls to memclr.
This occurs in the stdlib in 18 places.

The motivating example is clearing a byte slice:

benchmark                old ns/op     new ns/op     delta
BenchmarkGoMemclr5       3.31          3.26          -1.51%
BenchmarkGoMemclr16      13.7          3.28          -76.06%
BenchmarkGoMemclr64      50.8          4.14          -91.85%
BenchmarkGoMemclr256     157           6.02          -96.17%

Update #5373.

Change-Id: I99d3e6f5f268e8c6499b7e661df46403e5eb83e4
Reviewed-on: https://go-review.googlesource.com/2520
Reviewed-by: Keith Randall <khr@golang.org>
@bradfitz
Copy link
Contributor Author

bradfitz commented Jan 9, 2015

I consider this fixed. Optimizing non-zero cases isn't very interesting.

We can open another bug if people feel strongly about doing more.

@bradfitz bradfitz closed this as completed Jan 9, 2015
juniorz added a commit to twstrike/AwESome that referenced this issue Jul 2, 2015
It is optimized to use "memclr". See: golang/go#5373
@golang golang locked and limited conversation to collaborators Jun 24, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants