19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @bug 8143012
27 * @summary CRC32 Intrinsics support on SPARC
28 *
29 * @run main/othervm/timeout=720 -Xbatch compiler.intrinsics.zip.TestCRC32 -m
30 */
31
32 package compiler.intrinsics.zip;
33
34 import java.nio.ByteBuffer;
35 import java.util.zip.CRC32;
36 import java.util.zip.Checksum;
37
38 public class TestCRC32 {
39 public static void main(String[] args) {
40 int offset = Integer.getInteger("offset", 0);
41 int msgSize = Integer.getInteger("msgSize", 512);
42 boolean multi = false;
43 int iters = 20000;
44 int warmupIters = 20000;
45
46 if (args.length > 0) {
47 if (args[0].equals("-m")) {
48 multi = true;
49 } else {
50 iters = Integer.valueOf(args[0]);
51 }
52 if (args.length > 1) {
53 warmupIters = Integer.valueOf(args[1]);
54 }
55 }
56
57 if (multi) {
58 test_multi(warmupIters);
59 return;
60 }
61
62 System.out.println(" offset = " + offset);
63 System.out.println("msgSize = " + msgSize + " bytes");
64 System.out.println(" iters = " + iters);
65
66 byte[] b = initializedBytes(msgSize, offset);
67
68 CRC32 crc0 = new CRC32();
69 CRC32 crc1 = new CRC32();
70 CRC32 crc2 = new CRC32();
71
72 crc0.update(b, offset, msgSize);
73
74 System.out.println("-------------------------------------------------------");
75
76 /* warm up */
77 for (int i = 0; i < warmupIters; i++) {
78 crc1.reset();
79 crc1.update(b, offset, msgSize);
80 }
81
82 /* measure performance */
83 long start = System.nanoTime();
84 for (int i = 0; i < iters; i++) {
85 crc1.reset();
86 crc1.update(b, offset, msgSize);
87 }
88 long end = System.nanoTime();
89 double total = (double)(end - start)/1e9; // in seconds
90 double thruput = (double)msgSize*iters/1e6/total; // in MB/s
91 System.out.println("CRC32.update(byte[]) runtime = " + total + " seconds");
92 System.out.println("CRC32.update(byte[]) throughput = " + thruput + " MB/s");
93
94 /* check correctness */
95 for (int i = 0; i < iters; i++) {
96 crc1.reset();
97 crc1.update(b, offset, msgSize);
98 if (!check(crc0, crc1)) break;
99 }
100 report("CRCs", crc0, crc1);
101
102 System.out.println("-------------------------------------------------------");
103
104 ByteBuffer buf = ByteBuffer.allocateDirect(msgSize);
105 buf.put(b, offset, msgSize);
106 buf.flip();
107
108 /* warm up */
109 for (int i = 0; i < warmupIters; i++) {
110 crc2.reset();
111 crc2.update(buf);
112 buf.rewind();
113 }
114
115 /* measure performance */
116 start = System.nanoTime();
117 for (int i = 0; i < iters; i++) {
118 crc2.reset();
119 crc2.update(buf);
120 buf.rewind();
121 }
122 end = System.nanoTime();
123 total = (double)(end - start)/1e9; // in seconds
124 thruput = (double)msgSize*iters/1e6/total; // in MB/s
125 System.out.println("CRC32.update(ByteBuffer) runtime = " + total + " seconds");
126 System.out.println("CRC32.update(ByteBuffer) throughput = " + thruput + " MB/s");
127
128 /* check correctness */
129 for (int i = 0; i < iters; i++) {
130 crc2.reset();
131 crc2.update(buf);
132 buf.rewind();
133 if (!check(crc0, crc2)) break;
134 }
135 report("CRCs", crc0, crc2);
136
137 System.out.println("-------------------------------------------------------");
138 }
139
140 private static void report(String s, Checksum crc0, Checksum crc1) {
141 System.out.printf("%s: crc0 = %08x, crc1 = %08x\n",
142 s, crc0.getValue(), crc1.getValue());
143 }
144
145 private static boolean check(Checksum crc0, Checksum crc1) {
146 if (crc0.getValue() != crc1.getValue()) {
147 System.err.printf("ERROR: crc0 = %08x, crc1 = %08x\n",
148 crc0.getValue(), crc1.getValue());
149 return false;
150 }
151 return true;
152 }
153
154 private static byte[] initializedBytes(int M, int offset) {
155 byte[] bytes = new byte[M + offset];
156 for (int i = 0; i < offset; i++) {
157 bytes[i] = (byte) i;
158 }
159 for (int i = offset; i < bytes.length; i++) {
160 bytes[i] = (byte) (i - offset);
161 }
162 return bytes;
163 }
164
165 private static void test_multi(int iters) {
166 int len1 = 8; // the 8B/iteration loop
167 int len2 = 32; // the 32B/iteration loop
168 int len3 = 4096; // the 4KB/iteration loop
169
170 byte[] b = initializedBytes(len3*16, 0);
171 int[] offsets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512 };
172 int[] sizes = { 0, 1, 2, 3, 4, 5, 6, 7,
173 len1, len1+1, len1+2, len1+3, len1+4, len1+5, len1+6, len1+7,
174 len1*2, len1*2+1, len1*2+3, len1*2+5, len1*2+7,
175 len2, len2+1, len2+3, len2+5, len2+7,
176 len2*2, len2*4, len2*8, len2*16, len2*32, len2*64,
177 len3, len3+1, len3+3, len3+5, len3+7,
178 len3*2, len3*4, len3*8,
179 len1+len2, len1+len2+1, len1+len2+3, len1+len2+5, len1+len2+7,
180 len1+len3, len1+len3+1, len1+len3+3, len1+len3+5, len1+len3+7,
181 len2+len3, len2+len3+1, len2+len3+3, len2+len3+5, len2+len3+7,
182 len1+len2+len3, len1+len2+len3+1, len1+len2+len3+3,
183 len1+len2+len3+5, len1+len2+len3+7,
184 (len1+len2+len3)*2, (len1+len2+len3)*2+1, (len1+len2+len3)*2+3,
185 (len1+len2+len3)*2+5, (len1+len2+len3)*2+7,
186 (len1+len2+len3)*3, (len1+len2+len3)*3-1, (len1+len2+len3)*3-3,
187 (len1+len2+len3)*3-5, (len1+len2+len3)*3-7 };
188 CRC32[] crc0 = new CRC32[offsets.length*sizes.length];
189 CRC32[] crc1 = new CRC32[offsets.length*sizes.length];
190 int i, j, k;
191
192 System.out.printf("testing %d cases ...\n", offsets.length*sizes.length);
193
194 /* set the result from interpreter as reference */
195 for (i = 0; i < offsets.length; i++) {
196 for (j = 0; j < sizes.length; j++) {
197 crc0[i*sizes.length + j] = new CRC32();
198 crc1[i*sizes.length + j] = new CRC32();
199 crc0[i*sizes.length + j].update(b, offsets[i], sizes[j]);
200 }
201 }
202
203 /* warm up the JIT compiler and get result */
204 for (k = 0; k < iters; k++) {
205 for (i = 0; i < offsets.length; i++) {
206 for (j = 0; j < sizes.length; j++) {
207 crc1[i*sizes.length + j].reset();
208 crc1[i*sizes.length + j].update(b, offsets[i], sizes[j]);
209 }
210 }
211 }
212
213 /* check correctness */
214 for (i = 0; i < offsets.length; i++) {
215 for (j = 0; j < sizes.length; j++) {
216 if (!check(crc0[i*sizes.length + j], crc1[i*sizes.length + j])) {
217 System.out.printf("offsets[%d] = %d", i, offsets[i]);
218 System.out.printf("\tsizes[%d] = %d\n", j, sizes[j]);
219 }
220 }
221 }
222 }
223 }
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @bug 8143012
27 * @summary CRC32 Intrinsics support on SPARC
28 *
29 * @run main/othervm/timeout=720 -Xbatch compiler.intrinsics.zip.TestCRC32 -m
30 */
31
32 package compiler.intrinsics.zip;
33
34 import java.nio.ByteBuffer;
35 import java.util.zip.CRC32;
36 import java.util.zip.Checksum;
37
38 public class TestCRC32 {
39 // standard CRC32 polynomial
40 // coefficients in different forms
41 // normal: polyBits = 0x04c11db7 = 0b0000 0100 1100 0001 0001 1101 1011 0111
42 // reversed: polybits = 0xedb88320 = 0b1110 1101 1011 1000 1000 0011 0010 0000
43 // reversed reciprocal polybits = 0x82608edb = 0b1000 0010 0110 0000 1000 1110 1101 1011
44 //
45 // 0 5 9 13 17 21 25 29
46 // | | | | | | | |
47 // reversed shiftL 1 polyBits = 0x1db710641L = 0b1 1101 1011 0111 0001 0000 0110 0100 0001
48 final static long polyBits = (1L<<(32-32)) + (1L<<(32-26)) + (1L<<(32-23)) + (1L<<(32-22))
49 + (1L<<(32-16)) + (1L<<(32-12)) + (1L<<(32-11)) + (1L<<(32-10))
50 + (1L<<(32-8)) + (1L<<(32-7)) + (1L<<(32-5)) + (1L<<(32-4))
51 + (1L<<(32-2)) + (1L<<(32-1)) + (1L<<(32-0));
52 final static long polyBitsShifted = polyBits>>1;
53
54 public static void main(String[] args) throws Exception {
55 int offset = Integer.getInteger("offset", 0);
56 int msgSize = Integer.getInteger("msgSize", 512);
57 boolean multi = false;
58 int iters = 20000;
59 int warmupIters = 20000;
60
61 if (args.length > 0) {
62 if (args[0].equals("-m")) {
63 multi = true;
64 } else {
65 iters = Integer.valueOf(args[0]);
66 }
67 if (args.length > 1) {
68 warmupIters = Integer.valueOf(args[1]);
69 }
70 }
71
72 if (multi) {
73 test_multi(warmupIters);
74 return;
75 }
76
77 System.out.println(" offset = " + offset);
78 System.out.println("msgSize = " + msgSize + " bytes");
79 System.out.println(" iters = " + iters);
80
81 byte[] b = initializedBytes(msgSize, offset);
82
83 final long crcReference = update_byteLoop(0, b, offset);
84
85 CRC32 crc0 = new CRC32();
86 CRC32 crc1 = new CRC32();
87 CRC32 crc2 = new CRC32();
88
89 crc0.update(b, offset, msgSize);
90 check(crc0, crcReference);
91
92 System.out.println("-------------------------------------------------------");
93
94 /* warm up */
95 for (int i = 0; i < warmupIters; i++) {
96 crc1.reset();
97 crc1.update(b, offset, msgSize);
98 check(crc1, crcReference);
99 }
100
101 /* check correctness
102 * Do that before measuring performance
103 * to even better heat up involved methods.
104 */
105 for (int i = 0; i < iters; i++) {
106 crc1.reset();
107 crc1.update(b, offset, msgSize);
108 check(crc1, crcReference);
109 }
110 report("CRCs", crc1, crcReference);
111
112 /* measure performance
113 * Don't spoil times with error checking.
114 */
115 long start = System.nanoTime();
116 for (int i = 0; i < iters; i++) {
117 crc1.reset();
118 crc1.update(b, offset, msgSize);
119 }
120 long end = System.nanoTime();
121
122 double total = (double)(end - start)/1e9; // in seconds
123 double thruput = (double)msgSize*iters/1e6/total; // in MB/s
124 System.out.println("CRC32.update(byte[]) runtime = " + total + " seconds");
125 System.out.println("CRC32.update(byte[]) throughput = " + thruput + " MB/s");
126 report("CRCs", crc1, crcReference);
127
128 System.out.println("-------------------------------------------------------");
129
130 ByteBuffer buf = ByteBuffer.allocateDirect(msgSize);
131 buf.put(b, offset, msgSize);
132 buf.flip();
133
134 /* warm up */
135 for (int i = 0; i < warmupIters; i++) {
136 crc2.reset();
137 crc2.update(buf);
138 buf.rewind();
139 check(crc2, crcReference);
140 }
141
142 /* check correctness
143 * Do that before measuring performance
144 * to even better heat up involved methods.
145 */
146 for (int i = 0; i < iters; i++) {
147 crc2.reset();
148 crc2.update(buf);
149 buf.rewind();
150 check(crc2, crcReference);
151 }
152 report("CRCs", crc2, crcReference);
153
154 /* measure performance
155 * Don't spoil times with error checking.
156 */
157 start = System.nanoTime();
158 for (int i = 0; i < iters; i++) {
159 crc2.reset();
160 crc2.update(buf);
161 buf.rewind();
162 }
163 end = System.nanoTime();
164 total = (double)(end - start)/1e9; // in seconds
165 thruput = (double)msgSize*iters/1e6/total; // in MB/s
166 System.out.println("CRC32.update(ByteBuffer) runtime = " + total + " seconds");
167 System.out.println("CRC32.update(ByteBuffer) throughput = " + thruput + " MB/s");
168 report("CRCs", crc2, crcReference);
169
170 System.out.println("-------------------------------------------------------");
171 }
172
173 // Just a loop over a byte array, updating the CRC byte by byte.
174 public static long update_byteLoop(long crc, byte[] buf, int offset) {
175 return update_byteLoop(crc, buf, offset, buf.length-offset);
176 }
177
178 // Just a loop over a byte array, with given length, updating the CRC byte by byte.
179 public static long update_byteLoop(long crc, byte[] buf, int offset, int length) {
180 int end = length+offset;
181 for (int i = offset; i < end; i++) {
182 crc = update_singlebyte(crc, polyBitsShifted, buf[i]);
183 }
184 return crc;
185 }
186
187 // Straight-forward implementation of CRC update by one byte.
188 // We use this very basic implementation to calculate reference
189 // results. It is necessary to have full control over how the
190 // reference results are calculated. It is not sufficient to rely
191 // on the interpreter (or c1, or c2) to do the right thing.
192 public static long update_singlebyte(long crc, long polynomial, int val) {
193 crc = (crc ^ -1L) & 0x00000000ffffffffL; // use 1's complement of crc
194 crc = crc ^ (val&0xff); // XOR in next byte from stream
195 for (int i = 0; i < 8; i++) {
196 boolean bitset = (crc & 0x01L) != 0;
197
198 crc = crc>>1;
199 if (bitset) {
200 crc = crc ^ polynomial;
201 crc = crc & 0x00000000ffffffffL;
202 }
203 }
204 crc = (crc ^ -1L) & 0x00000000ffffffffL; // revert taking 1's complement
205 return crc;
206 }
207
208 private static void report(String s, Checksum crc, long crcReference) {
209 System.out.printf("%s: crc = %08x, crcReference = %08x\n",
210 s, crc.getValue(), crcReference);
211 }
212
213 private static void check(Checksum crc, long crcReference) throws Exception {
214 if (crc.getValue() != crcReference) {
215 System.err.printf("ERROR: crc = %08x, crcReference = %08x\n",
216 crc.getValue(), crcReference);
217 throw new Exception("TestCRC32 Error");
218 }
219 }
220
221 private static byte[] initializedBytes(int M, int offset) {
222 byte[] bytes = new byte[M + offset];
223 for (int i = 0; i < offset; i++) {
224 bytes[i] = (byte) i;
225 }
226 for (int i = offset; i < bytes.length; i++) {
227 bytes[i] = (byte) (i - offset);
228 }
229 return bytes;
230 }
231
232 private static void test_multi(int iters) throws Exception {
233 int len1 = 8; // the 8B/iteration loop
234 int len2 = 32; // the 32B/iteration loop
235 int len3 = 4096; // the 4KB/iteration loop
236
237 byte[] b = initializedBytes(len3*16, 0);
238 int[] offsets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32, 64, 128, 256, 512 };
239 int[] sizes = { 0, 1, 2, 3, 4, 5, 6, 7,
240 len1, len1+1, len1+2, len1+3, len1+4, len1+5, len1+6, len1+7,
241 len1*2, len1*2+1, len1*2+3, len1*2+5, len1*2+7,
242 len2, len2+1, len2+3, len2+5, len2+7,
243 len2*2, len2*4, len2*8, len2*16, len2*32, len2*64,
244 len3, len3+1, len3+3, len3+5, len3+7,
245 len3*2, len3*4, len3*8,
246 len1+len2, len1+len2+1, len1+len2+3, len1+len2+5, len1+len2+7,
247 len1+len3, len1+len3+1, len1+len3+3, len1+len3+5, len1+len3+7,
248 len2+len3, len2+len3+1, len2+len3+3, len2+len3+5, len2+len3+7,
249 len1+len2+len3, len1+len2+len3+1, len1+len2+len3+3,
250 len1+len2+len3+5, len1+len2+len3+7,
251 (len1+len2+len3)*2, (len1+len2+len3)*2+1, (len1+len2+len3)*2+3,
252 (len1+len2+len3)*2+5, (len1+len2+len3)*2+7,
253 (len1+len2+len3)*3, (len1+len2+len3)*3-1, (len1+len2+len3)*3-3,
254 (len1+len2+len3)*3-5, (len1+len2+len3)*3-7 };
255 CRC32[] crc1 = new CRC32[offsets.length*sizes.length];
256 long[] crcReference = new long[offsets.length*sizes.length];
257 int i, j, k;
258
259 System.out.printf("testing %d cases ...\n", offsets.length*sizes.length);
260
261 // Initialize CRC32 result arrays, CRC32 reference array.
262 // Reference is calculated using a very basic Java implementation.
263 for (i = 0; i < offsets.length; i++) {
264 for (j = 0; j < sizes.length; j++) {
265 crc1[i*sizes.length + j] = new CRC32();
266 crcReference[i*sizes.length + j] = update_byteLoop(0, b, offsets[i], sizes[j]);
267 }
268 }
269
270 // Warm up the JIT compiler. Over time, all methods involved will
271 // be executed by the interpreter, then get compiled by c1 and
272 // finally by c2. Each calculated CRC value must, in each iteration,
273 // be equal to the precalculated reference value for the test to pass.
274 for (k = 0; k < iters; k++) {
275 for (i = 0; i < offsets.length; i++) {
276 for (j = 0; j < sizes.length; j++) {
277 crc1[i*sizes.length + j].reset();
278 crc1[i*sizes.length + j].update(b, offsets[i], sizes[j]);
279 check(crc1[i*sizes.length + j], crcReference[i*sizes.length + j]);
280 }
281 }
282 }
283 }
284 }
|