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 DoubleScalar extends AbstractVectorBenchmark {
  38     @Param("1024")
  39     int size;
  40 
  41     double[] fill(IntFunction<Double> f) {
  42         double[] array = new double[size];
  43         for (int i = 0; i < array.length; i++) {
  44             array[i] = f.apply(i);
  45         }
  46         return array;
  47     }
  48 
  49     double[] as, bs, cs, rs;
  50     boolean[] ms, rms;
  51     int[] ss;
  52 
  53     @Setup
  54     public void init() {
  55         as = fill(i -> (double)(2*i));
  56         bs = fill(i -> (double)(i+1));
  57         cs = fill(i -> (double)(i+5));
  58         rs = fill(i -> (double)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<double[]> fa = vl -> as;
  66     final IntFunction<double[]> fb = vl -> bs;
  67     final IntFunction<double[]> fc = vl -> cs;
  68     final IntFunction<double[]> 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         double[] as = fa.apply(size);
  77         double[] bs = fb.apply(size);
  78         double[] rs = fr.apply(size);
  79 
  80         for (int i = 0; i < as.length; i++) {
  81             double a = as[i];
  82             double b = bs[i];
  83             rs[i] = (double)(a + b);
  84         }
  85 
  86         return rs;
  87     }
  88 
  89     @Benchmark
  90     public Object addMasked() {
  91         double[] as = fa.apply(size);
  92         double[] bs = fb.apply(size);
  93         double[] rs = fr.apply(size);
  94         boolean[] ms = fm.apply(size);
  95 
  96         for (int i = 0; i < as.length; i++) {
  97             double a = as[i];
  98             double b = bs[i];
  99             if (ms[i % ms.length]) {
 100                 rs[i] = (double)(a + b);
 101             } else {
 102                 rs[i] = a;
 103             }
 104         }
 105         return rs;
 106     }
 107 
 108     @Benchmark
 109     public Object sub() {
 110         double[] as = fa.apply(size);
 111         double[] bs = fb.apply(size);
 112         double[] rs = fr.apply(size);
 113 
 114         for (int i = 0; i < as.length; i++) {
 115             double a = as[i];
 116             double b = bs[i];
 117             rs[i] = (double)(a - b);
 118         }
 119 
 120         return rs;
 121     }
 122 
 123     @Benchmark
 124     public Object subMasked() {
 125         double[] as = fa.apply(size);
 126         double[] bs = fb.apply(size);
 127         double[] rs = fr.apply(size);
 128         boolean[] ms = fm.apply(size);
 129 
 130         for (int i = 0; i < as.length; i++) {
 131             double a = as[i];
 132             double b = bs[i];
 133             if (ms[i % ms.length]) {
 134                 rs[i] = (double)(a - b);
 135             } else {
 136                 rs[i] = a;
 137             }
 138         }
 139         return rs;
 140     }
 141 
 142 
 143     @Benchmark
 144     public Object div() {
 145         double[] as = fa.apply(size);
 146         double[] bs = fb.apply(size);
 147         double[] rs = fr.apply(size);
 148 
 149         for (int i = 0; i < as.length; i++) {
 150             double a = as[i];
 151             double b = bs[i];
 152             rs[i] = (double)(a / b);
 153         }
 154 
 155         return rs;
 156     }
 157 
 158 
 159 
 160     @Benchmark
 161     public Object divMasked() {
 162         double[] as = fa.apply(size);
 163         double[] bs = fb.apply(size);
 164         double[] rs = fr.apply(size);
 165         boolean[] ms = fm.apply(size);
 166 
 167         for (int i = 0; i < as.length; i++) {
 168             double a = as[i];
 169             double b = bs[i];
 170             if (ms[i % ms.length]) {
 171                 rs[i] = (double)(a / b);
 172             } else {
 173                 rs[i] = a;
 174             }
 175         }
 176         return rs;
 177     }
 178 
 179 
 180     @Benchmark
 181     public Object mul() {
 182         double[] as = fa.apply(size);
 183         double[] bs = fb.apply(size);
 184         double[] rs = fr.apply(size);
 185 
 186         for (int i = 0; i < as.length; i++) {
 187             double a = as[i];
 188             double b = bs[i];
 189             rs[i] = (double)(a * b);
 190         }
 191 
 192         return rs;
 193     }
 194 
 195     @Benchmark
 196     public Object mulMasked() {
 197         double[] as = fa.apply(size);
 198         double[] bs = fb.apply(size);
 199         double[] rs = fr.apply(size);
 200         boolean[] ms = fm.apply(size);
 201 
 202         for (int i = 0; i < as.length; i++) {
 203             double a = as[i];
 204             double b = bs[i];
 205             if (ms[i % ms.length]) {
 206                 rs[i] = (double)(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         double[] as = fa.apply(size);
 247         double[] bs = fb.apply(size);
 248         double[] rs = fr.apply(size);
 249 
 250         for (int i = 0; i < as.length; i++) {
 251             double a = as[i];
 252             double b = bs[i];
 253             rs[i] = (double)(Math.max(a, b));
 254         }
 255 
 256         return rs;
 257     }
 258 
 259     @Benchmark
 260     public Object min() {
 261         double[] as = fa.apply(size);
 262         double[] bs = fb.apply(size);
 263         double[] rs = fr.apply(size);
 264 
 265         for (int i = 0; i < as.length; i++) {
 266             double a = as[i];
 267             double b = bs[i];
 268             rs[i] = (double)(Math.min(a, b));
 269         }
 270 
 271         return rs;
 272     }
 273 
 274 
 275 
 276 
 277     @Benchmark
 278     public double addAll() {
 279         double[] as = fa.apply(size);
 280         double 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 double mulAll() {
 289         double[] as = fa.apply(size);
 290         double 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 double minAll() {
 299         double[] as = fa.apply(size);
 300         double r = Double.POSITIVE_INFINITY;
 301         for (int i = 0; i < as.length; i++) {
 302             r = (double)Math.min(r, as[i]);
 303         }
 304         return r;
 305     }
 306 
 307     @Benchmark
 308     public double maxAll() {
 309         double[] as = fa.apply(size);
 310         double r = Double.NEGATIVE_INFINITY;
 311         for (int i = 0; i < as.length; i++) {
 312             r = (double)Math.max(r, as[i]);
 313         }
 314         return r;
 315     }
 316 
 317 
 318 
 319     @Benchmark
 320     public boolean lessThan() {
 321         double[] as = fa.apply(size);
 322         double[] 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         double[] as = fa.apply(size);
 336         double[] 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         double[] as = fa.apply(size);
 350         double[] 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         double[] as = fa.apply(size);
 364         double[] 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         double[] as = fa.apply(size);
 378         double[] 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         double[] as = fa.apply(size);
 392         double[] 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         double[] as = fa.apply(size);
 406         double[] bs = fb.apply(size);
 407         double[] rs = fr.apply(size);
 408         boolean[] ms = fm.apply(size);
 409 
 410         for (int i = 0; i < as.length; i++) {
 411             double a = as[i];
 412             double 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         double[] as = fa.apply(size);
 421         int[] order = fs.apply(size);
 422         double[] rs = fr.apply(size);
 423 
 424         for (int i = 0; i < as.length; i += window) {
 425             for (int j = 0; j < window; j++) {
 426                 double 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 / Double.SIZE;
 438         return rearrangeShared(window);
 439     }
 440 
 441     @Benchmark
 442     public Object rearrange128() {
 443         int window = 128 / Double.SIZE;
 444         return rearrangeShared(window);
 445     }
 446 
 447     @Benchmark
 448     public Object rearrange256() {
 449         int window = 256 / Double.SIZE;
 450         return rearrangeShared(window);
 451     }
 452 
 453     @Benchmark
 454     public Object rearrange512() {
 455         int window = 512 / Double.SIZE;
 456         return rearrangeShared(window);
 457     }
 458 
 459 
 460     @Benchmark
 461     public Object sin() {
 462         double[] as = fa.apply(size);
 463         double[] rs = fr.apply(size);
 464 
 465         for (int i = 0; i < as.length; i++) {
 466             double a = as[i];
 467             rs[i] = (double)(Math.sin((double)a));
 468         }
 469 
 470         return rs;
 471     }
 472 
 473 
 474 
 475     @Benchmark
 476     public Object exp() {
 477         double[] as = fa.apply(size);
 478         double[] rs = fr.apply(size);
 479 
 480         for (int i = 0; i < as.length; i++) {
 481             double a = as[i];
 482             rs[i] = (double)(Math.exp((double)a));
 483         }
 484 
 485         return rs;
 486     }
 487 
 488 
 489 
 490     @Benchmark
 491     public Object log1p() {
 492         double[] as = fa.apply(size);
 493         double[] rs = fr.apply(size);
 494 
 495         for (int i = 0; i < as.length; i++) {
 496             double a = as[i];
 497             rs[i] = (double)(Math.log1p((double)a));
 498         }
 499 
 500         return rs;
 501     }
 502 
 503 
 504 
 505     @Benchmark
 506     public Object log() {
 507         double[] as = fa.apply(size);
 508         double[] rs = fr.apply(size);
 509 
 510         for (int i = 0; i < as.length; i++) {
 511             double a = as[i];
 512             rs[i] = (double)(Math.log((double)a));
 513         }
 514 
 515         return rs;
 516     }
 517 
 518 
 519 
 520     @Benchmark
 521     public Object log10() {
 522         double[] as = fa.apply(size);
 523         double[] rs = fr.apply(size);
 524 
 525         for (int i = 0; i < as.length; i++) {
 526             double a = as[i];
 527             rs[i] = (double)(Math.log10((double)a));
 528         }
 529 
 530         return rs;
 531     }
 532 
 533 
 534 
 535     @Benchmark
 536     public Object expm1() {
 537         double[] as = fa.apply(size);
 538         double[] rs = fr.apply(size);
 539 
 540         for (int i = 0; i < as.length; i++) {
 541             double a = as[i];
 542             rs[i] = (double)(Math.expm1((double)a));
 543         }
 544 
 545         return rs;
 546     }
 547 
 548 
 549 
 550     @Benchmark
 551     public Object cos() {
 552         double[] as = fa.apply(size);
 553         double[] rs = fr.apply(size);
 554 
 555         for (int i = 0; i < as.length; i++) {
 556             double a = as[i];
 557             rs[i] = (double)(Math.cos((double)a));
 558         }
 559 
 560         return rs;
 561     }
 562 
 563 
 564 
 565     @Benchmark
 566     public Object tan() {
 567         double[] as = fa.apply(size);
 568         double[] rs = fr.apply(size);
 569 
 570         for (int i = 0; i < as.length; i++) {
 571             double a = as[i];
 572             rs[i] = (double)(Math.tan((double)a));
 573         }
 574 
 575         return rs;
 576     }
 577 
 578 
 579 
 580     @Benchmark
 581     public Object sinh() {
 582         double[] as = fa.apply(size);
 583         double[] rs = fr.apply(size);
 584 
 585         for (int i = 0; i < as.length; i++) {
 586             double a = as[i];
 587             rs[i] = (double)(Math.sinh((double)a));
 588         }
 589 
 590         return rs;
 591     }
 592 
 593 
 594 
 595     @Benchmark
 596     public Object cosh() {
 597         double[] as = fa.apply(size);
 598         double[] rs = fr.apply(size);
 599 
 600         for (int i = 0; i < as.length; i++) {
 601             double a = as[i];
 602             rs[i] = (double)(Math.cosh((double)a));
 603         }
 604 
 605         return rs;
 606     }
 607 
 608 
 609 
 610     @Benchmark
 611     public Object tanh() {
 612         double[] as = fa.apply(size);
 613         double[] rs = fr.apply(size);
 614 
 615         for (int i = 0; i < as.length; i++) {
 616             double a = as[i];
 617             rs[i] = (double)(Math.tanh((double)a));
 618         }
 619 
 620         return rs;
 621     }
 622 
 623 
 624 
 625     @Benchmark
 626     public Object asin() {
 627         double[] as = fa.apply(size);
 628         double[] rs = fr.apply(size);
 629 
 630         for (int i = 0; i < as.length; i++) {
 631             double a = as[i];
 632             rs[i] = (double)(Math.asin((double)a));
 633         }
 634 
 635         return rs;
 636     }
 637 
 638 
 639 
 640     @Benchmark
 641     public Object acos() {
 642         double[] as = fa.apply(size);
 643         double[] rs = fr.apply(size);
 644 
 645         for (int i = 0; i < as.length; i++) {
 646             double a = as[i];
 647             rs[i] = (double)(Math.acos((double)a));
 648         }
 649 
 650         return rs;
 651     }
 652 
 653 
 654 
 655     @Benchmark
 656     public Object atan() {
 657         double[] as = fa.apply(size);
 658         double[] rs = fr.apply(size);
 659 
 660         for (int i = 0; i < as.length; i++) {
 661             double a = as[i];
 662             rs[i] = (double)(Math.atan((double)a));
 663         }
 664 
 665         return rs;
 666     }
 667 
 668 
 669 
 670     @Benchmark
 671     public Object cbrt() {
 672         double[] as = fa.apply(size);
 673         double[] rs = fr.apply(size);
 674 
 675         for (int i = 0; i < as.length; i++) {
 676             double a = as[i];
 677             rs[i] = (double)(Math.cbrt((double)a));
 678         }
 679 
 680         return rs;
 681     }
 682 
 683 
 684 
 685     @Benchmark
 686     public Object hypot() {
 687         double[] as = fa.apply(size);
 688         double[] bs = fb.apply(size);
 689         double[] rs = fr.apply(size);
 690 
 691         for (int i = 0; i < as.length; i++) {
 692             double a = as[i];
 693             double b = bs[i];
 694             rs[i] = (double)(Math.hypot((double)a, (double)b));
 695         }
 696 
 697         return rs;
 698     }
 699 
 700 
 701 
 702     @Benchmark
 703     public Object pow() {
 704         double[] as = fa.apply(size);
 705         double[] bs = fb.apply(size);
 706         double[] rs = fr.apply(size);
 707 
 708         for (int i = 0; i < as.length; i++) {
 709             double a = as[i];
 710             double b = bs[i];
 711             rs[i] = (double)(Math.pow((double)a, (double)b));
 712         }
 713 
 714         return rs;
 715     }
 716 
 717 
 718 
 719     @Benchmark
 720     public Object atan2() {
 721         double[] as = fa.apply(size);
 722         double[] bs = fb.apply(size);
 723         double[] rs = fr.apply(size);
 724 
 725         for (int i = 0; i < as.length; i++) {
 726             double a = as[i];
 727             double b = bs[i];
 728             rs[i] = (double)(Math.atan2((double)a, (double)b));
 729         }
 730 
 731         return rs;
 732     }
 733 
 734 
 735 
 736     @Benchmark
 737     public Object fma() {
 738         double[] as = fa.apply(size);
 739         double[] bs = fb.apply(size);
 740         double[] cs = fc.apply(size);
 741         double[] rs = fr.apply(size);
 742 
 743         for (int i = 0; i < as.length; i++) {
 744             double a = as[i];
 745             double b = bs[i];
 746             double c = cs[i];
 747             rs[i] = (double)(Math.fma(a, b, c));
 748         }
 749 
 750         return rs;
 751     }
 752 
 753 
 754 
 755 
 756     @Benchmark
 757     public Object fmaMasked() {
 758         double[] as = fa.apply(size);
 759         double[] bs = fb.apply(size);
 760         double[] cs = fc.apply(size);
 761         double[] rs = fr.apply(size);
 762         boolean[] ms = fm.apply(size);
 763 
 764         for (int i = 0; i < as.length; i++) {
 765             double a = as[i];
 766             double b = bs[i];
 767             double c = cs[i];
 768             if (ms[i % ms.length]) {
 769                 rs[i] = (double)(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         double[] as = fa.apply(size);
 781         double[] rs = fr.apply(size);
 782 
 783         for (int i = 0; i < as.length; i++) {
 784             double a = as[i];
 785             rs[i] = (double)(-((double)a));
 786         }
 787 
 788         return rs;
 789     }
 790 
 791     @Benchmark
 792     public Object negMasked() {
 793         double[] as = fa.apply(size);
 794         double[] rs = fr.apply(size);
 795         boolean[] ms = fm.apply(size);
 796 
 797         for (int i = 0; i < as.length; i++) {
 798             double a = as[i];
 799             boolean m = ms[i % ms.length];
 800             rs[i] = (m ? (double)(-((double)a)) : a);
 801         }
 802 
 803         return rs;
 804     }
 805 
 806     @Benchmark
 807     public Object abs() {
 808         double[] as = fa.apply(size);
 809         double[] rs = fr.apply(size);
 810 
 811         for (int i = 0; i < as.length; i++) {
 812             double a = as[i];
 813             rs[i] = (double)(Math.abs((double)a));
 814         }
 815 
 816         return rs;
 817     }
 818 
 819     @Benchmark
 820     public Object absMasked() {
 821         double[] as = fa.apply(size);
 822         double[] rs = fr.apply(size);
 823         boolean[] ms = fm.apply(size);
 824 
 825         for (int i = 0; i < as.length; i++) {
 826             double a = as[i];
 827             boolean m = ms[i % ms.length];
 828             rs[i] = (m ? (double)(Math.abs((double)a)) : a);
 829         }
 830 
 831         return rs;
 832     }
 833 
 834 
 835 
 836 
 837     @Benchmark
 838     public Object sqrt() {
 839         double[] as = fa.apply(size);
 840         double[] rs = fr.apply(size);
 841 
 842         for (int i = 0; i < as.length; i++) {
 843             double a = as[i];
 844             rs[i] = (double)(Math.sqrt((double)a));
 845         }
 846 
 847         return rs;
 848     }
 849 
 850 
 851 
 852     @Benchmark
 853     public Object sqrtMasked() {
 854         double[] as = fa.apply(size);
 855         double[] rs = fr.apply(size);
 856         boolean[] ms = fm.apply(size);
 857 
 858         for (int i = 0; i < as.length; i++) {
 859             double a = as[i];
 860             boolean m = ms[i % ms.length];
 861             rs[i] = (m ? (double)(Math.sqrt((double)a)) : a);
 862         }
 863 
 864         return rs;
 865     }
 866 
 867 
 868     @Benchmark
 869     public Object gatherBase0() {
 870         double[] as = fa.apply(size);
 871         int[] is    = fs.apply(size);
 872         double[] 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         double[] as = fa.apply(size);
 885         int[] is    = fs.apply(size);
 886         double[] 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 / Double.SIZE;
 901         return gather(window);
 902     }
 903 
 904     @Benchmark
 905     public Object gather128() {
 906         int window = 128 / Double.SIZE;
 907         return gather(window);
 908     }
 909 
 910     @Benchmark
 911     public Object gather256() {
 912         int window = 256 / Double.SIZE;
 913         return gather(window);
 914     }
 915 
 916     @Benchmark
 917     public Object gather512() {
 918         int window = 512 / Double.SIZE;
 919         return gather(window);
 920     }
 921 
 922 
 923 
 924     @Benchmark
 925     public Object scatterBase0() {
 926         double[] as = fa.apply(size);
 927         int[] is    = fs.apply(size);
 928         double[] 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         double[] as = fa.apply(size);
 940         int[] is    = fs.apply(size);
 941         double[] 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 / Double.SIZE;
 956         return scatter(window);
 957     }
 958 
 959     @Benchmark
 960     public Object scatter128() {
 961         int window = 128 / Double.SIZE;
 962         return scatter(window);
 963     }
 964 
 965     @Benchmark
 966     public Object scatter256() {
 967         int window = 256 / Double.SIZE;
 968         return scatter(window);
 969     }
 970 
 971     @Benchmark
 972     public Object scatter512() {
 973         int window = 512 / Double.SIZE;
 974         return scatter(window);
 975     }
 976 
 977 }
 978