Производительность метода 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));
}
}
информация о моем компьютере:
Количество потоков далеко от предельного числа ядра ЦП.
основной метод:
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
Я получил диаграмму пламени с асинхронным профилем