-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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/cgo: mark all the C functions as go:noescape #24450
Comments
I don't think this is safe. |
Yes, this is intentional and I don't see a way to avoid it. Closing this bug since there is nothing we can do. Sorry. |
@ianlancetaylor , is there a possibility to manually mark |
Currently I use the following "trick" to avoid memory allocations when passing pointers to Go array to C function: func f3(a []byte) {
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
C.f1(unsafe.Pointer(sh.Data))
} Unfortunately, this leads to the issue #14210 when |
There is no way to manually mark it. cgo is generating code that deliberately causes it to escape, to ensure that the value is not allocated on the stack. I don't know whether there is any better approach that will work for your application. This should probably be discussed on golang-nuts rather than in the issue tracker. |
Go allocates a copy of slice headers when they are passed to C functions. See golang/go#24450 for details. Avoid this by passing unsafe.Pointer as C.uintptr_t into C functions. Benchmark results: $ PAYLOAD=ZSTD_LICENSE go test -run=111 -bench='k[CD]' -benchmem -count=10 name old time/op new time/op delta Compression-4 21.2µs ± 5% 20.8µs ± 6% ~ (p=0.190 n=10+10) Decompression-4 7.37µs ± 5% 6.93µs ± 6% -5.95% (p=0.001 n=10+10) name old speed new speed delta Compression-4 62.5MB/s ± 5% 63.7MB/s ± 6% ~ (p=0.190 n=10+10) Decompression-4 180MB/s ± 5% 191MB/s ± 6% +6.35% (p=0.001 n=10+10) name old alloc/op new alloc/op delta Compression-4 96.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) Decompression-4 96.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Compression-4 4.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10) Decompression-4 4.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
What version of Go are you using (
go version
)?go tip
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?linux/amd64
What did you do?
Build the following code with
go build -gcflags=-m
:What did you expect to see?
a
shouldn't escape when callingC.f1
, since, according to cgo rules,C code may not keep a copy of a Go pointer after the call returns
.This means that all the C functions may be safely marked as
//go:noescape
in order to prevent from useless memory allocations when the argument to C function escapes to heap.What did you see instead?
a
escapes to heap, which leads to useless memory allocation:The text was updated successfully, but these errors were encountered: