Repository navigation
common/hexutil: hex encode/decode in simd #24410
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
Open
AskAlexSharov
wants to merge
32
commits into
main
Choose a base branch
from
alex/simdhex_37
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 10 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
2813baa
common/hexutil/simdhex: AVX2 lowercase hex encoder behind GOEXPERIMEN…
AskAlexSharov fc954d0
common/hexutil/simdhex: add table and SWAR scalar encoders to the bench
AskAlexSharov b42c834
common/hexutil: encode hex with an AVX2 kernel and a SWAR fallback
AskAlexSharov bb5b5fe
common/hexutil: drop the SWAR tail table, grow once in Bytes.AppendText
AskAlexSharov 77bb958
common/hexutil: cover Bytes.AppendText in the encoder test
AskAlexSharov ea8efa1
common/hexutil: drop the SWAR fallback, build without simd uses hex.E…
AskAlexSharov efd5b36
common/hexutil: keep hex.Encode for U256, too short for the vector path
AskAlexSharov 8c959d2
common/hexutil: AppendQuoted on top of AppendText
AskAlexSharov ad1aa43
common/hexutil: reslice in the AVX2 loop so it has no bounds checks
AskAlexSharov cc6feb4
ci: test the SIMD kernels with Go 1.27 and GOEXPERIMENT=simd
AskAlexSharov 873fe90
common/hexutil: test the non-AVX2 fallback of the simd build
AskAlexSharov 29f725f
Merge branch 'main' into alex/simdhex_37
AskAlexSharov 49af067
common/hexutil: drop the no-AVX2 test and the stdlib bench arm
AskAlexSharov 4468929
ci: run the SIMD hex test as a lint job step
AskAlexSharov 3dba162
common/hexutil: hex decoding by simd
AskAlexSharov 8fcedb7
common/hexutil: no AVX-512, close the control-byte hole, add NEON
AskAlexSharov d32cde6
common/hexutil: hex_amd64.go, hex_arm64.go, hex_generic.go
AskAlexSharov f7579da
common/hexutil: drop a no-op mask and a subsumed test loop
AskAlexSharov bb38cff
common/hexutil: name the AVX-512 instructions the ISA test rejects
AskAlexSharov 6abaa99
ci: cover every architecture the SIMD hex kernels build for
AskAlexSharov 9c3f46e
common/hexutil: reject EVEX encoding, not instruction names
AskAlexSharov f1f4f74
ci: run the arm64 hex test on a GitHub runner
AskAlexSharov 02ceae2
common/hexutil: build the ISA test only with the kernel it audits
AskAlexSharov db8e41b
ci: scope actions: write to the lint job
AskAlexSharov a57bd6e
common/hexutil: range over int in the decode fuzz loops
AskAlexSharov e70175d
common/hexutil: test every digit pair, odd lengths and writes past n
AskAlexSharov a00d691
common/hexutil: arm64 hex encode by table lookup, decode 32 chars per…
AskAlexSharov 731ff44
common/hexutil: amd64 hex encode two blocks per iteration, decode by …
AskAlexSharov 5a32b3a
common/hexutil: hex kernels in assembly, fed at most 64 KiB per call
AskAlexSharov fe96ffd
common/hexutil: keep short MarshalText and Encode buffers on the stack
AskAlexSharov 300a1f4
common/hexutil: pack decoded bytes with VPACKUSWB and VPERMQ
AskAlexSharov 900b6bb
common/hexutil: arm64 decode with instructions Go 1.26 assembles
AskAlexSharov File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| name: SIMD tests | ||
|
|
||
| # The simd/archsimd kernels only build with Go 1.27 and GOEXPERIMENT=simd, which the regular | ||
| # test jobs (Go from go.mod, default experiments) never compile. | ||
| on: | ||
| workflow_call: | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| simd: | ||
| runs-on: ubuntu-24.04 | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| with: | ||
| fetch-depth: 1 | ||
| persist-credentials: false | ||
|
|
||
| - uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: '1.27.x' | ||
| check-latest: true | ||
| cache: false | ||
|
|
||
| - name: Test the SIMD kernels | ||
| env: | ||
| GOEXPERIMENT: jsonv2,simd | ||
| GOTOOLCHAIN: local | ||
| run: go test -count=1 ./common/hexutil/... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Copyright 2026 The Erigon Authors | ||
| // This file is part of Erigon. | ||
| // | ||
| // Erigon is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU Lesser General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // Erigon is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public License | ||
| // along with Erigon. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| //go:build !(go1.27 && goexperiment.simd && amd64) | ||
|
|
||
| package hexutil | ||
|
|
||
| import "encoding/hex" | ||
|
|
||
| func encodeHex(dst, src []byte) { hex.Encode(dst, src) } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // Copyright 2026 The Erigon Authors | ||
| // This file is part of Erigon. | ||
| // | ||
| // Erigon is free software: you can redistribute it and/or modify | ||
| // it under the terms of the GNU Lesser General Public License as published by | ||
| // the Free Software Foundation, either version 3 of the License, or | ||
| // (at your option) any later version. | ||
| // | ||
| // Erigon is distributed in the hope that it will be useful, | ||
| // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| // GNU Lesser General Public License for more details. | ||
| // | ||
| // You should have received a copy of the GNU Lesser General Public License | ||
| // along with Erigon. If not, see <http://www.gnu.org/licenses/>. | ||
|
|
||
| //go:build go1.27 && goexperiment.simd && amd64 | ||
|
|
||
| package hexutil | ||
|
|
||
| import ( | ||
| "encoding/hex" | ||
| "simd/archsimd" | ||
| ) | ||
|
|
||
| var ( | ||
| hexDigits32 = [32]uint8{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', | ||
| '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'} | ||
| hasAVX2 = archsimd.X86.AVX2() | ||
| ) | ||
|
|
||
| // encodeHex is hex.Encode with whole 16-byte blocks done by AVX2. Each byte is widened to a | ||
| // uint16 holding its high nibble in the low byte and its low nibble in the high byte, so one | ||
| // in-lane byte shuffle turns the nibbles into digits in output order. | ||
| func encodeHex(dst, src []byte) { | ||
| if hasAVX2 { | ||
| digits := archsimd.LoadUint8x32Array(&hexDigits32) | ||
| low := archsimd.BroadcastUint16x16(0x0f) | ||
| for len(src) >= 16 && len(dst) >= 32 { | ||
| w := archsimd.LoadUint8x16Array((*[16]uint8)(src)).ExtendToUint16() | ||
| w = w.ShiftAllRight(4).Or(w.And(low).ShiftAllLeft(8)) | ||
| digits.PermuteOrZeroGrouped(w.AsUint8x32().AsInt8x32()).StoreArray((*[32]uint8)(dst)) | ||
| src, dst = src[16:], dst[32:] | ||
| } | ||
| } | ||
| hex.Encode(dst, src) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.