Go version
go version go1.27rc1 windows/amd64
Output of go env in your module/workspace:
set AR=ar
set CC=gcc
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_ENABLED=1
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set CXX=g++
set GCCGO=gccgo
set GO111MODULE=on
set GOAMD64=v1
set GOARCH=amd64
set GOAUTH=netrc
set GOBIN=C:\Users\8\go\bin
set GOCACHE=C:\Users\8\AppData\Local\go-build
set GOCACHEPROG=
set GODEBUG=
set GOENV=C:\Users\8\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\8\AppData\Local\Temp\go-build1360496246=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=E:\code\cc\go.mod
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\8\AppData\Local\Temp\go-build1360496246=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=E:\code\cc\go.mod
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\8\AppData\Local\Temp\go-build1360496246=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=E:\code\cc\go.mod
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\8\AppData\Local\Temp\go-build1360496246=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=E:\code\cc\go.mod
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=E:\code\cc\go.mod
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOMODCACHE=C:\Users\8\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPACKAGESDRIVER=
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.27rc1
set GOWORK=
set PKG_CONFIG=pkg-config
What did you do?
This is API usability feedback for the experimental Go 1.27 simd package, not a compiler crash report.
I am prototyping a vector-size-agnostic hash table using the new portable simd package.
The core probing operation is:
- Load a vector of tag bytes.
- Compare all lanes against a broadcast tag.
- Convert the resulting mask into lane indexes.
- Probe only matching lanes.
With simd/archsimd, this is direct:
words := archsimd.LoadUint8x32Array((*[32]uint8)(ptr))
bits := words.Equal(archsimd.BroadcastUint8x32(tag)).ToBits()
for bits != 0 {
lane := bits.TrailingZeros()
bits &= bits - 1
// check entry at lane
}
With portable simd, I can produce a simd.Mask8s:
words := simd.LoadUint8s(tags)
mask := words.Equal(simd.BroadcastUint8s(tag))
But I could not find a portable way to extract set lane indexes from simd.Mask8s.
The only practical path seems to be mask.ToArch() plus architecture-specific type switches:
switch m := mask.ToArch().(type) {
case archsimd.Mask8x16:
bits := uint64(m.ToBits())
case archsimd.Mask8x32:
bits := uint64(m.ToBits())
case archsimd.Mask8x64:
bits := m.ToBits()
}
What did you see happen?
The current portable simd.Mask8s API does not appear to provide a portable way to extract or iterate over the selected lanes.
For workloads such as hash-table probing, byte search, parsers, and scanners, the comparison mask is usually not the final result. The caller needs the lane indexes represented by the mask.
The portable simd.Mask8s API exposes operations such as And, Or, ToInt8s, and ToArch, but I could not find a direct portable way to enumerate or extract selected lanes.
The only practical workaround I found is to call mask.ToArch() and then switch on architecture-specific mask types such as archsimd.Mask8x16, archsimd.Mask8x32, and archsimd.Mask8x64, using their ToBits methods. That makes the probing loop architecture-specific again, which reduces the usefulness of the portable, vector-size-agnostic API for this class of workloads.
What did you expect to see?
I expected simd.Mask8s to provide a portable way to extract or enumerate selected lanes.
One possible API would be:
func (Mask8s) ToBits() uint64
This would be enough because current portable vectors are at least 128 bits and commonly 128/256/512 bits; for Mask8s, that is up to 64 lanes.
Alternatively, a width-independent iterator-style API would also work:
func (Mask8s) FirstSet() int
func (Mask8s) Clear(i int) Mask8s
func (Mask8s) NextSet(start int) int
The important part is not the exact API name, but that portable simd.Mask8s should let callers efficiently enumerate selected lanes without converting to simd/archsimd.
This came up while implementing a generic open-addressed hash table. The portable API can express the vector comparison, but without portable mask extraction the probing loop still has to be architecture-specific.
Go version
go version go1.27rc1 windows/amd64
Output of
go envin your module/workspace:What did you do?
This is API usability feedback for the experimental Go 1.27
simdpackage, not a compiler crash report.I am prototyping a vector-size-agnostic hash table using the new portable
simdpackage.The core probing operation is:
With
simd/archsimd, this is direct:With portable simd, I can produce a simd.Mask8s:
But I could not find a portable way to extract set lane indexes from simd.Mask8s.
The only practical path seems to be mask.ToArch() plus architecture-specific type switches:
What did you see happen?
The current portable
simd.Mask8sAPI does not appear to provide a portable way to extract or iterate over the selected lanes.For workloads such as hash-table probing, byte search, parsers, and scanners, the comparison mask is usually not the final result. The caller needs the lane indexes represented by the mask.
The portable
simd.Mask8sAPI exposes operations such asAnd,Or,ToInt8s, andToArch, but I could not find a direct portable way to enumerate or extract selected lanes.The only practical workaround I found is to call
mask.ToArch()and then switch on architecture-specific mask types such asarchsimd.Mask8x16,archsimd.Mask8x32, andarchsimd.Mask8x64, using theirToBitsmethods. That makes the probing loop architecture-specific again, which reduces the usefulness of the portable, vector-size-agnostic API for this class of workloads.What did you expect to see?
I expected
simd.Mask8sto provide a portable way to extract or enumerate selected lanes.One possible API would be:
This would be enough because current portable vectors are at least 128 bits and commonly 128/256/512 bits; for Mask8s, that is up to 64 lanes.
Alternatively, a width-independent iterator-style API would also work:
The important part is not the exact API name, but that portable simd.Mask8s should let callers efficiently enumerate selected lanes without converting to simd/archsimd.
This came up while implementing a generic open-addressed hash table. The portable API can express the vector comparison, but without portable mask extraction the probing loop still has to be architecture-specific.