1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 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 }