Skip to content

Commit 4294f29

Browse files
committed
Update aws-crt to 0.38.1
This is primarily to pick up the changes to how CRT handles the buffers passed to the checksum implementations to avoid as much copying as possible. Includes benchmarks for CRT provided checksums implementations.
1 parent 3ce1c9d commit 4294f29

File tree

3 files changed

+163
-1
lines changed

3 files changed

+163
-1
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Update `aws-crt` to `0.38.0`."
6+
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@
125125
<rxjava.version>2.2.21</rxjava.version>
126126
<commons-codec.verion>1.17.1</commons-codec.verion>
127127
<jmh.version>1.37</jmh.version>
128-
<awscrt.version>0.36.3</awscrt.version>
128+
<awscrt.version>0.38.0</awscrt.version>
129129

130130
<!--Test dependencies -->
131131
<junit5.version>5.10.0</junit5.version>
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.benchmark.checksum;
17+
18+
import org.openjdk.jmh.annotations.Benchmark;
19+
import org.openjdk.jmh.annotations.Param;
20+
import org.openjdk.jmh.annotations.Scope;
21+
import org.openjdk.jmh.annotations.Setup;
22+
import org.openjdk.jmh.annotations.State;
23+
import org.openjdk.jmh.infra.Blackhole;
24+
import software.amazon.awssdk.checksums.DefaultChecksumAlgorithm;
25+
import software.amazon.awssdk.checksums.SdkChecksum;
26+
import software.amazon.awssdk.checksums.internal.CrcCloneOnMarkChecksum;
27+
import software.amazon.awssdk.crt.checksums.CRC32C;
28+
29+
/**
30+
* Benchmarks for testing CRT implementations of checksums.
31+
* <p>
32+
* There are pitfalls with passing buffers to and from native code since it could lead to lots of copying.
33+
*/
34+
public class CrtChecksumBenchmark {
35+
private static final int KB = 1024;
36+
private static final int MB = 1024 * KB;
37+
private static final int PAYLOAD_SIZE = 512 * MB;
38+
39+
public enum Algorithm {
40+
CRC32C,
41+
CRC64,
42+
;
43+
}
44+
45+
public enum Size {
46+
SZ_512_KB(512 * KB),
47+
SZ_1_MB(MB),
48+
SZ_2_MB(2 * MB),
49+
SZ_4_MB(4 * MB),
50+
SZ_8_MB(8 * MB),
51+
SZ_16_MB(16 * MB),
52+
SZ_32_MB(32 * MB),
53+
SZ_64_MB(64 * MB),
54+
SZ_128_MB(128 * MB),
55+
SZ_256_MB(256 * MB);
56+
57+
private int numBytes;
58+
59+
private Size(int bytes) {
60+
61+
this.numBytes = bytes;
62+
}
63+
64+
public int getNumBytes() {
65+
return numBytes;
66+
}
67+
}
68+
69+
@State(Scope.Benchmark)
70+
public static class ChunkedState {
71+
private SdkChecksum crc;
72+
73+
private byte[] chunkData;
74+
75+
@Param({"SZ_512_KB", "SZ_1_MB", "SZ_2_MB", "SZ_4_MB", "SZ_8_MB", "SZ_16_MB", "SZ_32_MB", "SZ_64_MB", "SZ_128_MB", "SZ_256_MB"})
76+
private Size chunkSize;
77+
78+
@Param({"CRC64", "CRC32C"})
79+
private Algorithm algorithm;
80+
81+
@Setup
82+
public void setup () {
83+
crc = getSdkChecksum(algorithm);
84+
chunkData = new byte[chunkSize.getNumBytes()];
85+
}
86+
}
87+
88+
/**
89+
* Approximates where we feed a fixed number of bytes (PAYLOAD_BYTES), using different chunk sizes.
90+
*/
91+
@Benchmark
92+
public void chunked(ChunkedState s, Blackhole bh) {
93+
int chunkSize = s.chunkSize.getNumBytes();
94+
95+
int nChunks = PAYLOAD_SIZE / chunkSize;
96+
97+
s.crc.reset();
98+
for (int i = 0; i < nChunks; ++i) {
99+
s.crc.update(s.chunkData);
100+
}
101+
bh.consume(s.crc.getChecksumBytes());
102+
}
103+
104+
/**
105+
* This benchmark approximates use cases where crc64.update(byte[], offset, length) is called where length is
106+
* smaller than the length of byte[]. For example, the application might have a *large* read buffer, but only fills
107+
* a small portion of it and calls crc64.update() with only that portion.
108+
*/
109+
@State(Scope.Benchmark)
110+
public static class FixedInputBufferSizeState {
111+
@Param({"SZ_32_MB", "SZ_64_MB", "SZ_128_MB", "SZ_256_MB"})
112+
private Size fixedBufferSize;
113+
114+
@Param({"SZ_512_KB", "SZ_1_MB", "SZ_2_MB"})
115+
private Size chunkSize;
116+
117+
@Param({"CRC64", "CRC32C"})
118+
private Algorithm algorithm;
119+
120+
private byte[] buffer;
121+
122+
private SdkChecksum crc;
123+
124+
@Setup
125+
public void setup() {
126+
buffer = new byte[fixedBufferSize.getNumBytes()];
127+
crc = getSdkChecksum(algorithm);
128+
}
129+
}
130+
131+
@Benchmark
132+
public void fixedBufferSize(FixedInputBufferSizeState s, Blackhole bh) {
133+
int chunkSize = s.chunkSize.getNumBytes();
134+
135+
int nChunks = PAYLOAD_SIZE / chunkSize;
136+
137+
s.crc.reset();
138+
for (int i = 0; i < nChunks; ++i) {
139+
s.crc.update(s.buffer, 0, chunkSize);
140+
}
141+
bh.consume(s.crc.getChecksumBytes());
142+
}
143+
144+
private static SdkChecksum getSdkChecksum(Algorithm algorithm) {
145+
switch (algorithm) {
146+
case CRC32C:
147+
// Construct directly instead of using forAlgorithm because it
148+
// will pick up the JVM provided one if it's available.
149+
return new CrcCloneOnMarkChecksum(new CRC32C());
150+
case CRC64:
151+
return SdkChecksum.forAlgorithm(DefaultChecksumAlgorithm.CRC64NVME);
152+
default:
153+
throw new RuntimeException("Unsupported algorithm: " + algorithm);
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)