1 /* 2 * Copyright (c) 2018, 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 21 * questions. 22 */ 23 24 package benchmark.jdk.incubator.vector; 25 26 import java.util.concurrent.TimeUnit; 27 import java.util.function.IntFunction; 28 29 import org.openjdk.jmh.annotations.*; 30 31 @BenchmarkMode(Mode.Throughput) 32 @OutputTimeUnit(TimeUnit.MILLISECONDS) 33 @State(Scope.Benchmark) 34 @Warmup(iterations = 3, time = 1) 35 @Measurement(iterations = 5, time = 1) 36 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) 37 public class FloatScalar extends AbstractVectorBenchmark { 38 @Param("1024") 39 int size; 40 41 float[] fill(IntFunction<Float> f) { 42 float[] array = new float[size]; 43 for (int i = 0; i < array.length; i++) { 44 array[i] = f.apply(i); 45 } 46 return array; 47 } 48 49 float[] as, bs, cs, rs; 50 boolean[] ms, rms; 51 int[] ss; 52 53 @Setup 54 public void init() { 55 as = fill(i -> (float)(2*i)); 56 bs = fill(i -> (float)(i+1)); 57 cs = fill(i -> (float)(i+5)); 58 rs = fill(i -> (float)0); 59 ms = fillMask(size, i -> (i % 2) == 0); 60 rms = fillMask(size, i -> false); 61 62 ss = fillInt(size, i -> RANDOM.nextInt(Math.max(i,1))); 63 } 64 65 final IntFunction<float[]> fa = vl -> as; 66 final IntFunction<float[]> fb = vl -> bs; 67 final IntFunction<float[]> fc = vl -> cs; 68 final IntFunction<float[]> fr = vl -> rs; 69 final IntFunction<boolean[]> fm = vl -> ms; 70 final IntFunction<boolean[]> fmr = vl -> rms; 71 final IntFunction<int[]> fs = vl -> ss; 72 73 74 @Benchmark 75 public Object add() { 76 float[] as = fa.apply(size); 77 float[] bs = fb.apply(size); 78 float[] rs = fr.apply(size); 79 80 for (int i = 0; i < as.length; i++) { 81 float a = as[i]; 82 float b = bs[i]; 83 rs[i] = (float)(a + b); 84 } 85 86 return rs; 87 } 88 89 @Benchmark 90 public Object addMasked() { 91 float[] as = fa.apply(size); 92 float[] bs = fb.apply(size); 93 float[] rs = fr.apply(size); 94 boolean[] ms = fm.apply(size); 95 96 for (int i = 0; i < as.length; i++) { 97 float a = as[i]; 98 float b = bs[i]; 99 if (ms[i % ms.length]) { 100 rs[i] = (float)(a + b); 101 } else { 102 rs[i] = a; 103 } 104 } 105 return rs; 106 } 107 108 @Benchmark 109 public Object sub() { 110 float[] as = fa.apply(size); 111 float[] bs = fb.apply(size); 112 float[] rs = fr.apply(size); 113 114 for (int i = 0; i < as.length; i++) { 115 float a = as[i]; 116 float b = bs[i]; 117 rs[i] = (float)(a - b); 118 } 119 120 return rs; 121 } 122 123 @Benchmark 124 public Object subMasked() { 125 float[] as = fa.apply(size); 126 float[] bs = fb.apply(size); 127 float[] rs = fr.apply(size); 128 boolean[] ms = fm.apply(size); 129 130 for (int i = 0; i < as.length; i++) { 131 float a = as[i]; 132 float b = bs[i]; 133 if (ms[i % ms.length]) { 134 rs[i] = (float)(a - b); 135 } else { 136 rs[i] = a; 137 } 138 } 139 return rs; 140 } 141 142 143 @Benchmark 144 public Object div() { 145 float[] as = fa.apply(size); 146 float[] bs = fb.apply(size); 147 float[] rs = fr.apply(size); 148 149 for (int i = 0; i < as.length; i++) { 150 float a = as[i]; 151 float b = bs[i]; 152 rs[i] = (float)(a / b); 153 } 154 155 return rs; 156 } 157 158 159 160 @Benchmark 161 public Object divMasked() { 162 float[] as = fa.apply(size); 163 float[] bs = fb.apply(size); 164 float[] rs = fr.apply(size); 165 boolean[] ms = fm.apply(size); 166 167 for (int i = 0; i < as.length; i++) { 168 float a = as[i]; 169 float b = bs[i]; 170 if (ms[i % ms.length]) { 171 rs[i] = (float)(a / b); 172 } else { 173 rs[i] = a; 174 } 175 } 176 return rs; 177 } 178 179 180 @Benchmark 181 public Object mul() { 182 float[] as = fa.apply(size); 183 float[] bs = fb.apply(size); 184 float[] rs = fr.apply(size); 185 186 for (int i = 0; i < as.length; i++) { 187 float a = as[i]; 188 float b = bs[i]; 189 rs[i] = (float)(a * b); 190 } 191 192 return rs; 193 } 194 195 @Benchmark 196 public Object mulMasked() { 197 float[] as = fa.apply(size); 198 float[] bs = fb.apply(size); 199 float[] rs = fr.apply(size); 200 boolean[] ms = fm.apply(size); 201 202 for (int i = 0; i < as.length; i++) { 203 float a = as[i]; 204 float b = bs[i]; 205 if (ms[i % ms.length]) { 206 rs[i] = (float)(a * b); 207 } else { 208 rs[i] = a; 209 } 210 } 211 return rs; 212 } 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 @Benchmark 245 public Object max() { 246 float[] as = fa.apply(size); 247 float[] bs = fb.apply(size); 248 float[] rs = fr.apply(size); 249 250 for (int i = 0; i < as.length; i++) { 251 float a = as[i]; 252 float b = bs[i]; 253 rs[i] = (float)(Math.max(a, b)); 254 } 255 256 return rs; 257 } 258 259 @Benchmark 260 public Object min() { 261 float[] as = fa.apply(size); 262 float[] bs = fb.apply(size); 263 float[] rs = fr.apply(size); 264 265 for (int i = 0; i < as.length; i++) { 266 float a = as[i]; 267 float b = bs[i]; 268 rs[i] = (float)(Math.min(a, b)); 269 } 270 271 return rs; 272 } 273 274 275 276 277 @Benchmark 278 public float addAll() { 279 float[] as = fa.apply(size); 280 float r = 0; 281 for (int i = 0; i < as.length; i++) { 282 r += as[i]; 283 } 284 return r; 285 } 286 287 @Benchmark 288 public float mulAll() { 289 float[] as = fa.apply(size); 290 float r = 1; 291 for (int i = 0; i < as.length; i++) { 292 r *= as[i]; 293 } 294 return r; 295 } 296 297 @Benchmark 298 public float minAll() { 299 float[] as = fa.apply(size); 300 float r = Float.POSITIVE_INFINITY; 301 for (int i = 0; i < as.length; i++) { 302 r = (float)Math.min(r, as[i]); 303 } 304 return r; 305 } 306 307 @Benchmark 308 public float maxAll() { 309 float[] as = fa.apply(size); 310 float r = Float.NEGATIVE_INFINITY; 311 for (int i = 0; i < as.length; i++) { 312 r = (float)Math.max(r, as[i]); 313 } 314 return r; 315 } 316 317 318 319 @Benchmark 320 public boolean lessThan() { 321 float[] as = fa.apply(size); 322 float[] bs = fb.apply(size); 323 324 boolean r = false; 325 for (int i = 0; i < as.length; i++) { 326 boolean m = (as[i] < bs[i]); 327 r |= m; // accumulate so JIT can't eliminate the computation 328 } 329 330 return r; 331 } 332 333 @Benchmark 334 public boolean greaterThan() { 335 float[] as = fa.apply(size); 336 float[] bs = fb.apply(size); 337 338 boolean r = false; 339 for (int i = 0; i < as.length; i++) { 340 boolean m = (as[i] > bs[i]); 341 r |= m; // accumulate so JIT can't eliminate the computation 342 } 343 344 return r; 345 } 346 347 @Benchmark 348 public boolean equal() { 349 float[] as = fa.apply(size); 350 float[] bs = fb.apply(size); 351 352 boolean r = false; 353 for (int i = 0; i < as.length; i++) { 354 boolean m = (as[i] == bs[i]); 355 r |= m; // accumulate so JIT can't eliminate the computation 356 } 357 358 return r; 359 } 360 361 @Benchmark 362 public boolean notEqual() { 363 float[] as = fa.apply(size); 364 float[] bs = fb.apply(size); 365 366 boolean r = false; 367 for (int i = 0; i < as.length; i++) { 368 boolean m = (as[i] != bs[i]); 369 r |= m; // accumulate so JIT can't eliminate the computation 370 } 371 372 return r; 373 } 374 375 @Benchmark 376 public boolean lessThanEq() { 377 float[] as = fa.apply(size); 378 float[] bs = fb.apply(size); 379 380 boolean r = false; 381 for (int i = 0; i < as.length; i++) { 382 boolean m = (as[i] <= bs[i]); 383 r |= m; // accumulate so JIT can't eliminate the computation 384 } 385 386 return r; 387 } 388 389 @Benchmark 390 public boolean greaterThanEq() { 391 float[] as = fa.apply(size); 392 float[] bs = fb.apply(size); 393 394 boolean r = false; 395 for (int i = 0; i < as.length; i++) { 396 boolean m = (as[i] >= bs[i]); 397 r |= m; // accumulate so JIT can't eliminate the computation 398 } 399 400 return r; 401 } 402 403 @Benchmark 404 public Object blend() { 405 float[] as = fa.apply(size); 406 float[] bs = fb.apply(size); 407 float[] rs = fr.apply(size); 408 boolean[] ms = fm.apply(size); 409 410 for (int i = 0; i < as.length; i++) { 411 float a = as[i]; 412 float b = bs[i]; 413 boolean m = ms[i % ms.length]; 414 rs[i] = (m ? b : a); 415 } 416 417 return rs; 418 } 419 Object rearrangeShared(int window) { 420 float[] as = fa.apply(size); 421 int[] order = fs.apply(size); 422 float[] rs = fr.apply(size); 423 424 for (int i = 0; i < as.length; i += window) { 425 for (int j = 0; j < window; j++) { 426 float a = as[i+j]; 427 int pos = order[j]; 428 rs[i + pos] = a; 429 } 430 } 431 432 return rs; 433 } 434 435 @Benchmark 436 public Object rearrange064() { 437 int window = 64 / Float.SIZE; 438 return rearrangeShared(window); 439 } 440 441 @Benchmark 442 public Object rearrange128() { 443 int window = 128 / Float.SIZE; 444 return rearrangeShared(window); 445 } 446 447 @Benchmark 448 public Object rearrange256() { 449 int window = 256 / Float.SIZE; 450 return rearrangeShared(window); 451 } 452 453 @Benchmark 454 public Object rearrange512() { 455 int window = 512 / Float.SIZE; 456 return rearrangeShared(window); 457 } 458 459 460 @Benchmark 461 public Object sin() { 462 float[] as = fa.apply(size); 463 float[] rs = fr.apply(size); 464 465 for (int i = 0; i < as.length; i++) { 466 float a = as[i]; 467 rs[i] = (float)(Math.sin((double)a)); 468 } 469 470 return rs; 471 } 472 473 474 475 @Benchmark 476 public Object exp() { 477 float[] as = fa.apply(size); 478 float[] rs = fr.apply(size); 479 480 for (int i = 0; i < as.length; i++) { 481 float a = as[i]; 482 rs[i] = (float)(Math.exp((double)a)); 483 } 484 485 return rs; 486 } 487 488 489 490 @Benchmark 491 public Object log1p() { 492 float[] as = fa.apply(size); 493 float[] rs = fr.apply(size); 494 495 for (int i = 0; i < as.length; i++) { 496 float a = as[i]; 497 rs[i] = (float)(Math.log1p((double)a)); 498 } 499 500 return rs; 501 } 502 503 504 505 @Benchmark 506 public Object log() { 507 float[] as = fa.apply(size); 508 float[] rs = fr.apply(size); 509 510 for (int i = 0; i < as.length; i++) { 511 float a = as[i]; 512 rs[i] = (float)(Math.log((double)a)); 513 } 514 515 return rs; 516 } 517 518 519 520 @Benchmark 521 public Object log10() { 522 float[] as = fa.apply(size); 523 float[] rs = fr.apply(size); 524 525 for (int i = 0; i < as.length; i++) { 526 float a = as[i]; 527 rs[i] = (float)(Math.log10((double)a)); 528 } 529 530 return rs; 531 } 532 533 534 535 @Benchmark 536 public Object expm1() { 537 float[] as = fa.apply(size); 538 float[] rs = fr.apply(size); 539 540 for (int i = 0; i < as.length; i++) { 541 float a = as[i]; 542 rs[i] = (float)(Math.expm1((double)a)); 543 } 544 545 return rs; 546 } 547 548 549 550 @Benchmark 551 public Object cos() { 552 float[] as = fa.apply(size); 553 float[] rs = fr.apply(size); 554 555 for (int i = 0; i < as.length; i++) { 556 float a = as[i]; 557 rs[i] = (float)(Math.cos((double)a)); 558 } 559 560 return rs; 561 } 562 563 564 565 @Benchmark 566 public Object tan() { 567 float[] as = fa.apply(size); 568 float[] rs = fr.apply(size); 569 570 for (int i = 0; i < as.length; i++) { 571 float a = as[i]; 572 rs[i] = (float)(Math.tan((double)a)); 573 } 574 575 return rs; 576 } 577 578 579 580 @Benchmark 581 public Object sinh() { 582 float[] as = fa.apply(size); 583 float[] rs = fr.apply(size); 584 585 for (int i = 0; i < as.length; i++) { 586 float a = as[i]; 587 rs[i] = (float)(Math.sinh((double)a)); 588 } 589 590 return rs; 591 } 592 593 594 595 @Benchmark 596 public Object cosh() { 597 float[] as = fa.apply(size); 598 float[] rs = fr.apply(size); 599 600 for (int i = 0; i < as.length; i++) { 601 float a = as[i]; 602 rs[i] = (float)(Math.cosh((double)a)); 603 } 604 605 return rs; 606 } 607 608 609 610 @Benchmark 611 public Object tanh() { 612 float[] as = fa.apply(size); 613 float[] rs = fr.apply(size); 614 615 for (int i = 0; i < as.length; i++) { 616 float a = as[i]; 617 rs[i] = (float)(Math.tanh((double)a)); 618 } 619 620 return rs; 621 } 622 623 624 625 @Benchmark 626 public Object asin() { 627 float[] as = fa.apply(size); 628 float[] rs = fr.apply(size); 629 630 for (int i = 0; i < as.length; i++) { 631 float a = as[i]; 632 rs[i] = (float)(Math.asin((double)a)); 633 } 634 635 return rs; 636 } 637 638 639 640 @Benchmark 641 public Object acos() { 642 float[] as = fa.apply(size); 643 float[] rs = fr.apply(size); 644 645 for (int i = 0; i < as.length; i++) { 646 float a = as[i]; 647 rs[i] = (float)(Math.acos((double)a)); 648 } 649 650 return rs; 651 } 652 653 654 655 @Benchmark 656 public Object atan() { 657 float[] as = fa.apply(size); 658 float[] rs = fr.apply(size); 659 660 for (int i = 0; i < as.length; i++) { 661 float a = as[i]; 662 rs[i] = (float)(Math.atan((double)a)); 663 } 664 665 return rs; 666 } 667 668 669 670 @Benchmark 671 public Object cbrt() { 672 float[] as = fa.apply(size); 673 float[] rs = fr.apply(size); 674 675 for (int i = 0; i < as.length; i++) { 676 float a = as[i]; 677 rs[i] = (float)(Math.cbrt((double)a)); 678 } 679 680 return rs; 681 } 682 683 684 685 @Benchmark 686 public Object hypot() { 687 float[] as = fa.apply(size); 688 float[] bs = fb.apply(size); 689 float[] rs = fr.apply(size); 690 691 for (int i = 0; i < as.length; i++) { 692 float a = as[i]; 693 float b = bs[i]; 694 rs[i] = (float)(Math.hypot((double)a, (double)b)); 695 } 696 697 return rs; 698 } 699 700 701 702 @Benchmark 703 public Object pow() { 704 float[] as = fa.apply(size); 705 float[] bs = fb.apply(size); 706 float[] rs = fr.apply(size); 707 708 for (int i = 0; i < as.length; i++) { 709 float a = as[i]; 710 float b = bs[i]; 711 rs[i] = (float)(Math.pow((double)a, (double)b)); 712 } 713 714 return rs; 715 } 716 717 718 719 @Benchmark 720 public Object atan2() { 721 float[] as = fa.apply(size); 722 float[] bs = fb.apply(size); 723 float[] rs = fr.apply(size); 724 725 for (int i = 0; i < as.length; i++) { 726 float a = as[i]; 727 float b = bs[i]; 728 rs[i] = (float)(Math.atan2((double)a, (double)b)); 729 } 730 731 return rs; 732 } 733 734 735 736 @Benchmark 737 public Object fma() { 738 float[] as = fa.apply(size); 739 float[] bs = fb.apply(size); 740 float[] cs = fc.apply(size); 741 float[] rs = fr.apply(size); 742 743 for (int i = 0; i < as.length; i++) { 744 float a = as[i]; 745 float b = bs[i]; 746 float c = cs[i]; 747 rs[i] = (float)(Math.fma(a, b, c)); 748 } 749 750 return rs; 751 } 752 753 754 755 756 @Benchmark 757 public Object fmaMasked() { 758 float[] as = fa.apply(size); 759 float[] bs = fb.apply(size); 760 float[] cs = fc.apply(size); 761 float[] rs = fr.apply(size); 762 boolean[] ms = fm.apply(size); 763 764 for (int i = 0; i < as.length; i++) { 765 float a = as[i]; 766 float b = bs[i]; 767 float c = cs[i]; 768 if (ms[i % ms.length]) { 769 rs[i] = (float)(Math.fma(a, b, c)); 770 } else { 771 rs[i] = a; 772 } 773 } 774 return rs; 775 } 776 777 778 @Benchmark 779 public Object neg() { 780 float[] as = fa.apply(size); 781 float[] rs = fr.apply(size); 782 783 for (int i = 0; i < as.length; i++) { 784 float a = as[i]; 785 rs[i] = (float)(-((float)a)); 786 } 787 788 return rs; 789 } 790 791 @Benchmark 792 public Object negMasked() { 793 float[] as = fa.apply(size); 794 float[] rs = fr.apply(size); 795 boolean[] ms = fm.apply(size); 796 797 for (int i = 0; i < as.length; i++) { 798 float a = as[i]; 799 boolean m = ms[i % ms.length]; 800 rs[i] = (m ? (float)(-((float)a)) : a); 801 } 802 803 return rs; 804 } 805 806 @Benchmark 807 public Object abs() { 808 float[] as = fa.apply(size); 809 float[] rs = fr.apply(size); 810 811 for (int i = 0; i < as.length; i++) { 812 float a = as[i]; 813 rs[i] = (float)(Math.abs((float)a)); 814 } 815 816 return rs; 817 } 818 819 @Benchmark 820 public Object absMasked() { 821 float[] as = fa.apply(size); 822 float[] rs = fr.apply(size); 823 boolean[] ms = fm.apply(size); 824 825 for (int i = 0; i < as.length; i++) { 826 float a = as[i]; 827 boolean m = ms[i % ms.length]; 828 rs[i] = (m ? (float)(Math.abs((float)a)) : a); 829 } 830 831 return rs; 832 } 833 834 835 836 837 @Benchmark 838 public Object sqrt() { 839 float[] as = fa.apply(size); 840 float[] rs = fr.apply(size); 841 842 for (int i = 0; i < as.length; i++) { 843 float a = as[i]; 844 rs[i] = (float)(Math.sqrt((double)a)); 845 } 846 847 return rs; 848 } 849 850 851 852 @Benchmark 853 public Object sqrtMasked() { 854 float[] as = fa.apply(size); 855 float[] rs = fr.apply(size); 856 boolean[] ms = fm.apply(size); 857 858 for (int i = 0; i < as.length; i++) { 859 float a = as[i]; 860 boolean m = ms[i % ms.length]; 861 rs[i] = (m ? (float)(Math.sqrt((double)a)) : a); 862 } 863 864 return rs; 865 } 866 867 868 @Benchmark 869 public Object gatherBase0() { 870 float[] as = fa.apply(size); 871 int[] is = fs.apply(size); 872 float[] rs = fr.apply(size); 873 874 for (int i = 0; i < as.length; i++) { 875 int ix = 0 + is[i]; 876 rs[i] = as[ix]; 877 } 878 879 return rs; 880 } 881 882 883 Object gather(int window) { 884 float[] as = fa.apply(size); 885 int[] is = fs.apply(size); 886 float[] rs = fr.apply(size); 887 888 for (int i = 0; i < as.length; i += window) { 889 for (int j = 0; j < window; j++) { 890 int ix = i + is[i + j]; 891 rs[i + j] = as[ix]; 892 } 893 } 894 895 return rs; 896 } 897 898 @Benchmark 899 public Object gather064() { 900 int window = 64 / Float.SIZE; 901 return gather(window); 902 } 903 904 @Benchmark 905 public Object gather128() { 906 int window = 128 / Float.SIZE; 907 return gather(window); 908 } 909 910 @Benchmark 911 public Object gather256() { 912 int window = 256 / Float.SIZE; 913 return gather(window); 914 } 915 916 @Benchmark 917 public Object gather512() { 918 int window = 512 / Float.SIZE; 919 return gather(window); 920 } 921 922 923 924 @Benchmark 925 public Object scatterBase0() { 926 float[] as = fa.apply(size); 927 int[] is = fs.apply(size); 928 float[] rs = fr.apply(size); 929 930 for (int i = 0; i < as.length; i++) { 931 int ix = 0 + is[i]; 932 rs[ix] = as[i]; 933 } 934 935 return rs; 936 } 937 938 Object scatter(int window) { 939 float[] as = fa.apply(size); 940 int[] is = fs.apply(size); 941 float[] rs = fr.apply(size); 942 943 for (int i = 0; i < as.length; i += window) { 944 for (int j = 0; j < window; j++) { 945 int ix = i + is[i + j]; 946 rs[ix] = as[i + j]; 947 } 948 } 949 950 return rs; 951 } 952 953 @Benchmark 954 public Object scatter064() { 955 int window = 64 / Float.SIZE; 956 return scatter(window); 957 } 958 959 @Benchmark 960 public Object scatter128() { 961 int window = 128 / Float.SIZE; 962 return scatter(window); 963 } 964 965 @Benchmark 966 public Object scatter256() { 967 int window = 256 / Float.SIZE; 968 return scatter(window); 969 } 970 971 @Benchmark 972 public Object scatter512() { 973 int window = 512 / Float.SIZE; 974 return scatter(window); 975 } 976 977 } 978