Почему производительность метода modPow в BigInteger уменьшается с увеличением количества потоков? - PullRequest
0 голосов
/ 17 апреля 2019

Производительность метода modPow в BigInteger уменьшается с увеличением количества потоков.Переменные-члены имеют уровень потока и не должны мешать друг другу.

тестовый код теста

package com.talkingdata.opal.integration.symmetry.test;

import java.math.BigInteger;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;

@Threads(3)
@BenchmarkMode({Mode.AverageTime})
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 3, timeUnit = TimeUnit.SECONDS)
@State(Scope.Thread)
public class BigInetgerTest {

  @Setup
  public void init() {
    System.out.println("init:" + Thread.currentThread().getName());
    m = new BigInteger(
        "23102926163894804087468123845710955522238616569973353666239281949381051504551107360224306915645591442126969367657705430485746630194363134197282145402137496269572666746400440267844001070710891170019593928247889219946313036136160469214589902672935747681518472609981550373853654832707994073047370743370794391428670156851861824033969965168801027151081979879199373777395119996586955588065252135175109759281180503879410538517857534026402833729199373986365997415163253052422745035555497837505700225170627737903279421848273562122194826772338221878855543785028138290857341786447649895870946906474600198233990840527227839018238");
    ki = new BigInteger(
        "15496440288162419743268865114718257026885852313393508981474715221247140659575649380767994818172205420737192128574550076158981589552379214454159707302643163377814248952866015163322720213833249792410504477853431675639144135121119309034212137557381478542811241062421295329899396524651982321353860248201123787675894854005120584982976827832766435148510565563246764483917116360298494738360322791669514381959902756409009769298597889063173534343555581813116322134507007988747435656868578866321886606974476570934420927075393527376424244368884854766550653763850949818570822087960406683778581342937865788766804181937608463131857");
    p = new BigInteger(
        "27490896491489933992335324412569064612936644033659513179033017851327970216503296052491992976141549398201926199899588430101761196079157975703190131823229250106593153163655759253193643838508347060103568847805004457541248662429424153065534929351429845548643935657179253524125542257935535470543855771942241949526306435288473106976439156680014892693560941587038760913532303771463223029959086784861633301252525277074123146731837131167003251939861023095487264155821033565607389379286168868855925138310714581578711756536246844281245559500184650926517289810292587014812981652258232654229507008153238338553726865482037835778213");
  }

  private BigInteger m;
  private BigInteger ki;
  private BigInteger p;


  @Benchmark
  public void modPow(Blackhole bh) {
    bh.consume(m.modPow(ki, p));
  }



}

информация о моем компьютере:

machine info

Количество потоков далеко от предельного числа ядра ЦП.

основной метод:

package com.talkingdata.opal.integration.symmetry.main;

import com.talkingdata.opal.integration.symmetry.test.BigInetgerTest;
import java.time.LocalTime;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

public class BigIntegerMain {

  public static void main(String[] args) throws RunnerException {
    String name = BigInetgerTest.class.getName();
    String s = LocalTime.now().toString();
    Options opt = new OptionsBuilder()
        .include(name)
        .forks(1)
        .build();

    new Runner(opt).run();
  }

}

Результат теста: 1 поток: 4754.657us / op 20thread: 26436.544us / op

 thread number:1
 Benchmark              Mode  Cnt     Score     Error  Units
 BigInetgerTest.modPow  avgt    5  4754.657 ± 310.503  us/op
 thread number:2
 Benchmark              Mode  Cnt     Score     Error  Units
 BigInetgerTest.modPow  avgt    5  4765.872 ± 219.227  us/op
 thread number:4
 Benchmark              Mode  Cnt     Score     Error  Units
 BigInetgerTest.modPow  avgt    5  5786.041 ± 220.751  us/op
 thread number:20
 Benchmark              Mode  Cnt      Score     Error  Units
 BigInetgerTest.modPow  avgt    5  26436.544 ± 566.881  us/op

И я добавляю jmh stackprofiler в случае 20 потоков.вот результат:

Secondary result "com.talkingdata.opal.integration.symmetry.test.BigInetgerTest.modPow:·stack":
Stack profiler:

....[Thread state distributions]....................................................................
 93.0%         RUNNABLE
  4.5%         TIMED_WAITING
  2.5%         WAITING

....[Thread state: RUNNABLE]........................................................................
 88.0%  94.6% java.math.BigInteger.oddModPow
  4.5%   4.9% java.net.SocketInputStream.socketRead0
  0.3%   0.3% java.math.MutableBigInteger.divWord
  0.1%   0.1% jdk.internal.misc.Unsafe.unpark
  0.1%   0.1% java.math.BigInteger.materialize
  0.0%   0.0% java.math.BigInteger.leftShift
  0.0%   0.0% java.lang.ThreadLocal$ThreadLocalMap.access$000
  0.0%   0.0% jdk.internal.reflect.GeneratedMethodAccessor1.invoke
  0.0%   0.0% java.lang.Class.cast
  0.0%   0.0% java.util.concurrent.atomic.AtomicInteger.getAndDecrement

....[Thread state: TIMED_WAITING]...................................................................
  4.5% 100.0% java.lang.Object.wait

....[Thread state: WAITING].........................................................................
  2.5% 100.0% jdk.internal.misc.Unsafe.park

Я получил диаграмму пламени с асинхронным профилем

flame diagram

...