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

Comments

Projects
None yet
8 participants
@bradfitz
Member

bradfitz commented Apr 29, 2013

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

This comment has been minimized.

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

This comment has been minimized.

Member

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

This comment has been minimized.

Contributor

rsc commented May 1, 2013

Comment 3:

Yes, it should work for any zero value.
@cznic

This comment has been minimized.

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

This comment has been minimized.

Contributor

rsc commented Jun 3, 2013

Comment 5:

Labels changed: added go1.2maybe.

@rsc

This comment has been minimized.

Contributor

rsc commented Jul 30, 2013

Comment 6:

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

@robpike

This comment has been minimized.

Contributor

robpike commented Aug 20, 2013

Comment 7:

Labels changed: removed go1.3.

@rsc

This comment has been minimized.

Contributor

rsc commented Nov 27, 2013

Comment 8:

Labels changed: added go1.3maybe.

@alberts

This comment has been minimized.

Contributor

alberts commented Nov 27, 2013

Comment 9:

Had to implement an object pool. Needed this.
@rsc

This comment has been minimized.

Contributor

rsc commented Dec 4, 2013

Comment 10:

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

@rsc

This comment has been minimized.

Contributor

rsc commented Dec 4, 2013

Comment 11:

Labels changed: added repo-main.

@gopherbot

This comment has been minimized.

gopherbot commented Dec 10, 2013

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

This comment has been minimized.

Contributor

davecheney commented Dec 10, 2013

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

This comment has been minimized.

gopherbot commented Dec 10, 2013

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

This comment has been minimized.

gopherbot commented Jul 9, 2014

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

This comment has been minimized.

Contributor

josharian commented Sep 3, 2014

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

cmd/gc: optimize memclr of slices and arrays
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

cmd/gc: optimize memclr of slices and arrays
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

This comment has been minimized.

Member

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 Jan 9, 2015

juniorz added a commit to twstrike/AwESome that referenced this issue Jul 2, 2015

Using a for loop to zeroing memory is better
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.