diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1d953f4 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use nix diff --git a/.gitignore b/.gitignore index b63da45..e841327 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,10 @@ build/ !**/src/main/**/build/ !**/src/test/**/build/ +.direnv/ + ### IntelliJ IDEA ### -.idea/modules.xml -.idea/jarRepositories.xml -.idea/compiler.xml -.idea/libraries/ +.idea *.iws *.iml *.ipr @@ -39,4 +38,8 @@ bin/ .vscode/ ### Mac OS ### -.DS_Store \ No newline at end of file +.DS_Store + +# JCStress +jcstress-results-*.bin.gz +results/ diff --git a/README.md b/README.md index 6495c30..0eb4312 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/AwTYhPar) # Лабораторная работа № 1: определение достижимости параллелизма и реализация параллельных алгоритмов. Шаги выполнения: diff --git a/build.gradle.kts b/build.gradle.kts index 3341beb..9919064 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,8 @@ repositories { dependencies { testImplementation(kotlin("test")) + testImplementation("org.openjdk.jcstress:jcstress-core:0.16") + testAnnotationProcessor("org.openjdk.jcstress:jcstress-core:0.16") } tasks.test { @@ -24,4 +26,16 @@ kotlin { application { mainClass.set("MainKt") -} \ No newline at end of file +} + +tasks.register("jcstress") { + group = "verification" + description = "Run JCStress stress tests" + mainClass.set("org.openjdk.jcstress.Main") + classpath = sourceSets.test.get().runtimeClasspath + dependsOn("testClasses") + val argsProp = project.findProperty("jcstressArgs") as String? + if (!argsProp.isNullOrBlank()) { + args = argsProp.split("\\s+".toRegex()) + } +} diff --git a/plot.py b/plot.py new file mode 100755 index 0000000..649637e --- /dev/null +++ b/plot.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +import fileinput + +import matplotlib.pyplot as plt +import numpy as np + + +def get_data(): + for line in fileinput.input(encoding="utf-8"): + v, e, time = map(int, line.strip().split()) + load = 100 * e / (v * (v - 1) // 2) + yield [np.log10(v), load, np.log10(time)] + + +DATA = np.array(list(get_data())) +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}) +ax.scatter(*DATA.T) +ax.set_xlabel("Vertices (log10)") +ax.set_ylabel("Edge Load") +ax.set_zlabel("Time (log10)") +plt.show() diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..3b84f0c --- /dev/null +++ b/shell.nix @@ -0,0 +1,18 @@ +{ + pkgs ? import { }, +}: +pkgs.mkShellNoCC { + preferLocalBuild = true; + allowSubstitutes = false; + + name = "par-prog-lab1"; + packages = with pkgs; [ + jdk8 + (python3.withPackages ( + p: with p; [ + matplotlib + numpy + ] + )) + ]; +} diff --git a/src/main/java/MainKt.java b/src/main/java/MainKt.java new file mode 100644 index 0000000..fbcfa97 --- /dev/null +++ b/src/main/java/MainKt.java @@ -0,0 +1,38 @@ +import org.itmo.Graph; +import org.itmo.RandomGraphGenerator; + +import java.util.Random; + +public class MainKt { + public static void main(String[] args) { + final RandomGraphGenerator generator = new RandomGraphGenerator(); + final Random random = new Random(4); + for (int i = 0; i < 5; i++) { + System.err.println("Warmup " + i); + generator.generateGraph(random, 100_000, 10_000_000); + } + final int[] sizes = {10, 100, 1000, 10_000, 10_000, 50_000, 100_000}; + for (final int size : sizes) { + for (int i = 0; i <= size / 5; i += Math.max(1, size / 50)) { + final int numEdges = i * i; + if (numEdges < size) { + continue; + } + if (numEdges > size * (size - 1) / 2) { + break; + } + if (numEdges > 50_000_000) { + break; + } + System.out.print(size + " " + numEdges + " "); + System.out.flush(); + final Graph graph = generator.generateGraph(random, size, numEdges); + final long start = System.nanoTime(); + graph.parallelBFS(0); + final long end = System.nanoTime(); + final long duration = end - start; + System.out.println(duration); + } + } + } +} diff --git a/src/main/java/org/itmo/AtomicBooleanArray.java b/src/main/java/org/itmo/AtomicBooleanArray.java new file mode 100644 index 0000000..df2bfc1 --- /dev/null +++ b/src/main/java/org/itmo/AtomicBooleanArray.java @@ -0,0 +1,24 @@ +package org.itmo; + +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicIntegerArray; + +public final class AtomicBooleanArray { + private final AtomicIntegerArray inner; + + public AtomicBooleanArray(int size) { + inner = new AtomicIntegerArray(size); + } + + public boolean getAndSet(int i, boolean value) { + return inner.getAndSet(i, value ? 1 : 0) != 0; + } + + public boolean[] toArray() { + final boolean[] result = new boolean[inner.length()]; + for (int i = 0; i < result.length; i++) { + result[i] = inner.get(i) != 0; + } + return result; + } +} diff --git a/src/main/java/org/itmo/Graph.java b/src/main/java/org/itmo/Graph.java index 141a0b6..03430d9 100644 --- a/src/main/java/org/itmo/Graph.java +++ b/src/main/java/org/itmo/Graph.java @@ -1,11 +1,12 @@ package org.itmo; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -class Graph { +public class Graph { private final int V; private final ArrayList[] adjList; @@ -23,11 +24,57 @@ void addEdge(int src, int dest) { } } - void parallelBFS(int startVertex) { + public AtomicBooleanArray parallelBFS(int startVertex) { + final int parallelism = Runtime.getRuntime().availableProcessors(); + final ExecutorService pool = Executors.newFixedThreadPool(parallelism); + final AtomicBooleanArray visited = new AtomicBooleanArray(V); + visited.getAndSet(startVertex, true); + ArrayList queue = new ArrayList<>(); + queue.add(startVertex); + try { + while (!queue.isEmpty()) { + // Can't use runnable because of the `pool.invokeAll` signature. + final List>> tasks = new ArrayList<>(parallelism); + + final int frontSize = queue.size(); + final int perTask = (frontSize - 1 + parallelism) / parallelism; + + for (int i_ = 0; i_ < parallelism; i_++) { + final int i = i_; + tasks.add(() -> { + final List result = new LinkedList<>(); + for (int j = 0; j < perTask; ++j) { + final int index = i * perTask + j; + if (index >= frontSize) { + break; + } + final int v = queue.get(index); + for (int u : adjList[v]) { + if (!visited.getAndSet(u, true)) { + result.add(u); + } + } + } + return result; + }); + } + final List>> results = pool.invokeAll(tasks); + queue.clear(); + for (Future> result : results) { + assert result.isDone(); + queue.addAll(result.get()); + } + } + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } finally { + pool.shutdown(); + } + return visited; } //Generated by ChatGPT - void bfs(int startVertex) { + boolean[] bfs(int startVertex) { boolean[] visited = new boolean[V]; LinkedList queue = new LinkedList<>(); @@ -45,6 +92,18 @@ void bfs(int startVertex) { } } } + return visited; } + @Override + public String toString() { + final StringBuilder sb = new StringBuilder(); + sb.append(V).append(":"); + for (int v = 0; v < V; v++) { + for (int u : adjList[v]) { + sb.append("\n\t").append(v).append(" -> ").append(u); + } + } + return sb.toString(); + } } diff --git a/src/test/java/org/itmo/RandomGraphGenerator.java b/src/main/java/org/itmo/RandomGraphGenerator.java similarity index 98% rename from src/test/java/org/itmo/RandomGraphGenerator.java rename to src/main/java/org/itmo/RandomGraphGenerator.java index fdb888c..9f60b27 100644 --- a/src/test/java/org/itmo/RandomGraphGenerator.java +++ b/src/main/java/org/itmo/RandomGraphGenerator.java @@ -18,7 +18,7 @@ private int unpackV(long key) { return (int) (key & 0xffffffffL); } - Graph generateGraph(Random r, int size, int numEdges) { + public Graph generateGraph(Random r, int size, int numEdges) { if (numEdges < size - 1) throw new IllegalArgumentException("We need min size-1 edges"); long maxDirected = (long) size * (size - 1); if (numEdges > maxDirected) throw new IllegalArgumentException("Too many edges for directed graph without self-loops"); diff --git a/src/test/java/org/itmo/BFSJCStressTest.java b/src/test/java/org/itmo/BFSJCStressTest.java new file mode 100644 index 0000000..756212f --- /dev/null +++ b/src/test/java/org/itmo/BFSJCStressTest.java @@ -0,0 +1,51 @@ + +package org.itmo; + +import org.openjdk.jcstress.annotations.*; +import org.openjdk.jcstress.infra.results.I_Result; + +import java.util.Random; + +@JCStressTest +@State +@Outcome(id = "0", expect = Expect.ACCEPTABLE, desc = "Everything is ok") +@Outcome(id = "-2", expect = Expect.FORBIDDEN, desc = "Exception thrown") +@Outcome(id = "-1", expect = Expect.FORBIDDEN, desc = "Test not run") +public class BFSJCStressTest { + private int result = -1; + + @Actor + public void actor() { + this.result = run(); + } + + private static int run() { + final Random r = new Random(42); + final int startVertex = 0; + final int vert = 1000; + final int edges = 10_000; + final Graph graph = new RandomGraphGenerator().generateGraph(r, vert, edges); + final boolean[] expected = graph.bfs(startVertex); + final boolean[] actual; + try { + actual = graph.parallelBFS(startVertex).toArray(); + } catch (Exception e) { + return -2; + } + if (actual.length != expected.length) { + return -3; + } + int result = 0; + for (int i = 0; i < actual.length; i++) { + if (actual[i] != expected[i]) { + result++; + } + } + return result; + } + + @Arbiter + public void arbiter(I_Result result) { + result.r1 = this.result; + } +} \ No newline at end of file diff --git a/src/test/java/org/itmo/BFSTest.java b/src/test/java/org/itmo/BFSTest.java index 7bf9098..d959a6a 100644 --- a/src/test/java/org/itmo/BFSTest.java +++ b/src/test/java/org/itmo/BFSTest.java @@ -4,11 +4,8 @@ import java.io.FileWriter; import java.io.IOException; -import java.nio.Buffer; -import java.util.HashSet; +import java.util.Arrays; import java.util.Random; -import java.util.function.BiFunction; -import java.util.stream.IntStream; public class BFSTest { @@ -49,4 +46,29 @@ private long executeParallelBfsAndGetTime(Graph g) { return endTime - startTime; } + @Test + public void fuzz() { + Random r = new Random(42); + for (int iter_ = 0; iter_ < 1000; iter_++) { + final int size = 100 + r.nextInt(1000); + final int connections = size - 1 + r.nextInt(Math.max(size * size / 2 - 2 * size, 0)); + System.out.println("--------------------------"); + System.out.println("Generating graph of size " + size + " ...wait"); + Graph g = new RandomGraphGenerator().generateGraph(r, size, connections); + System.out.println("Generation completed!\nStarting bfs"); + final int startVertex = 0; + final boolean[] expected = g.bfs(startVertex); + final boolean[] actual = g.parallelBFS(startVertex).toArray(); + if (!Arrays.equals(expected, actual)) { + System.err.println(g); + System.err.println(Arrays.toString(expected)); + for (int i = 0; i < size; i++) { + if (expected[i] != actual[i]) { + System.err.println(i + ": " + expected[i] + " -> " + actual[i]); + } + } + throw new RuntimeException(); + } + } + } } diff --git a/tmp/dump.txt b/tmp/dump.txt new file mode 100644 index 0000000..b6e6bff --- /dev/null +++ b/tmp/dump.txt @@ -0,0 +1,427 @@ +2025-10-14 03:31:25 +Full thread dump OpenJDK 64-Bit Server VM (25.462-b08 mixed mode): + +"Attach Listener" #201 daemon prio=9 os_prio=0 tid=0x00007f0774001000 nid=0x19eab waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"pool-15-thread-12" #200 prio=5 os_prio=0 tid=0x00007f07e823d000 nid=0x19ded waiting on condition [0x00007f07ceef9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-11" #199 prio=5 os_prio=0 tid=0x00007f07e823c800 nid=0x19dec waiting on condition [0x00007f07ce8f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-10" #198 prio=5 os_prio=0 tid=0x00007f07e8227000 nid=0x19deb waiting on condition [0x00007f07cebf9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-9" #197 prio=5 os_prio=0 tid=0x00007f07e8233800 nid=0x19dea waiting on condition [0x00007f07ce7f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-8" #196 prio=5 os_prio=0 tid=0x00007f07e8230000 nid=0x19de9 waiting on condition [0x00007f07ceaf9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-7" #195 prio=5 os_prio=0 tid=0x00007f07e8231800 nid=0x19de8 waiting on condition [0x00007f07ceff9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b2f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) + at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) + at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - None + +"pool-15-thread-6" #194 prio=5 os_prio=0 tid=0x00007f07e822c800 nid=0x19de7 waiting for monitor entry [0x00007f07ce9f9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:51) + - waiting to lock <0x000000077b22b650> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22c718> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"pool-15-thread-5" #193 prio=5 os_prio=0 tid=0x00007f07e8228800 nid=0x19de6 waiting for monitor entry [0x00007f07ce6f9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b650> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22c450> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"pool-15-thread-4" #192 prio=5 os_prio=0 tid=0x00007f07e823a800 nid=0x19de5 waiting for monitor entry [0x00007f07cedf9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b7a0> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b710> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22c188> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"pool-15-thread-3" #191 prio=5 os_prio=0 tid=0x00007f07e822e000 nid=0x19de4 waiting for monitor entry [0x00007f07ce4f9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b7a0> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22bec0> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"pool-15-thread-2" #190 prio=5 os_prio=0 tid=0x00007f07e8238800 nid=0x19de3 waiting for monitor entry [0x00007f07cecf9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b680> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22bbf8> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"pool-15-thread-1" #189 prio=5 os_prio=0 tid=0x00007f07e8235000 nid=0x19de2 waiting for monitor entry [0x00007f07ce5f9000] + java.lang.Thread.State: BLOCKED (on object monitor) + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b7a0> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b680> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + + Locked ownable synchronizers: + - <0x000000077b22b8e0> (a java.util.concurrent.ThreadPoolExecutor$Worker) + +"ForkJoinPool.commonPool-worker-10" #19 daemon prio=5 os_prio=0 tid=0x00007f0760005000 nid=0x19d36 waiting on condition [0x00007f07cf0f9000] + java.lang.Thread.State: TIMED_WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-3" #20 daemon prio=5 os_prio=0 tid=0x00007f074c001000 nid=0x19d35 waiting on condition [0x00007f07cf1f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-1" #18 daemon prio=5 os_prio=0 tid=0x00007f0750001000 nid=0x19d34 waiting on condition [0x00007f07cf2f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-15" #16 daemon prio=5 os_prio=0 tid=0x00007f0760003000 nid=0x19d33 waiting on condition [0x00007f07cf3f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-13" #14 daemon prio=5 os_prio=0 tid=0x00007f0754003000 nid=0x19d30 waiting on condition [0x00007f07cf6f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-2" #11 daemon prio=5 os_prio=0 tid=0x00007f07e821e800 nid=0x19d2d waiting on condition [0x00007f07cf9f9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"ForkJoinPool.commonPool-worker-9" #10 daemon prio=5 os_prio=0 tid=0x00007f07e821d000 nid=0x19d2c waiting on condition [0x00007f07cfaf9000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x00000006d0001d70> (a java.util.concurrent.ForkJoinPool) + at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) + at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) + at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175) + + Locked ownable synchronizers: + - None + +"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x00007f07e80e7000 nid=0x19d2a runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C1 CompilerThread3" #8 daemon prio=9 os_prio=0 tid=0x00007f07e80d2000 nid=0x19d29 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C2 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f07e80cf800 nid=0x19d28 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f07e80ce000 nid=0x19d27 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f07e80cb000 nid=0x19d26 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f07e80c8000 nid=0x19d25 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + + Locked ownable synchronizers: + - None + +"Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f07e8094800 nid=0x19d24 in Object.wait() [0x00007f07d4686000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait(Native Method) + - waiting on <0x00000006d0065e80> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) + - locked <0x00000006d0065e80> (a java.lang.ref.ReferenceQueue$Lock) + at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) + at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:188) + + Locked ownable synchronizers: + - None + +"Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f07e8090000 nid=0x19d23 in Object.wait() [0x00007f07d4786000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait(Native Method) + - waiting on <0x00000006d0065ec0> (a java.lang.ref.Reference$Lock) + at java.lang.Object.wait(Object.java:502) + at java.lang.ref.Reference.tryHandlePending(Reference.java:191) + - locked <0x00000006d0065ec0> (a java.lang.ref.Reference$Lock) + at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) + + Locked ownable synchronizers: + - None + +"main" #1 prio=5 os_prio=0 tid=0x00007f07e800a800 nid=0x19d17 waiting on condition [0x00007f07ecbfe000] + java.lang.Thread.State: WAITING (parking) + at sun.misc.Unsafe.park(Native Method) + - parking to wait for <0x000000077b22b8c0> (a java.util.concurrent.FutureTask) + at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) + at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:429) + at java.util.concurrent.FutureTask.get(FutureTask.java:191) + at java.util.concurrent.AbstractExecutorService.invokeAll(AbstractExecutorService.java:244) + at org.itmo.Graph.parallelBFS(Graph.java:67) + at MainKt.main(MainKt.java:12) + + Locked ownable synchronizers: + - None + +"VM Thread" os_prio=0 tid=0x00007f07e8086800 nid=0x19d22 runnable + +"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f07e8020800 nid=0x19d18 runnable + +"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f07e8022800 nid=0x19d19 runnable + +"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f07e8024000 nid=0x19d1a runnable + +"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f07e8026000 nid=0x19d1b runnable + +"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x00007f07e8028000 nid=0x19d1c runnable + +"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x00007f07e8029800 nid=0x19d1d runnable + +"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x00007f07e802b800 nid=0x19d1e runnable + +"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x00007f07e802d800 nid=0x19d1f runnable + +"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x00007f07e802f000 nid=0x19d20 runnable + +"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x00007f07e8031000 nid=0x19d21 runnable + +"VM Periodic Task Thread" os_prio=0 tid=0x00007f07e80ea000 nid=0x19d2b waiting on condition + +JNI global references: 217 + + +Found one Java-level deadlock: +============================= +"pool-15-thread-6": + waiting to lock monitor 0x00007f072c005aa8 (object 0x000000077b22b650, a java.util.concurrent.locks.ReentrantLock), + which is held by "pool-15-thread-5" +"pool-15-thread-5": + waiting to lock monitor 0x00007f077c004068 (object 0x000000077b22b770, a java.util.concurrent.locks.ReentrantLock), + which is held by "pool-15-thread-2" +"pool-15-thread-2": + waiting to lock monitor 0x00007f077c003fb8 (object 0x000000077b22b680, a java.util.concurrent.locks.ReentrantLock), + which is held by "pool-15-thread-1" +"pool-15-thread-1": + waiting to lock monitor 0x00007f077c004c18 (object 0x000000077b22b7a0, a java.util.concurrent.locks.ReentrantLock), + which is held by "pool-15-thread-3" +"pool-15-thread-3": + waiting to lock monitor 0x00007f077c004068 (object 0x000000077b22b770, a java.util.concurrent.locks.ReentrantLock), + which is held by "pool-15-thread-2" + +Java stack information for the threads listed above: +=================================================== +"pool-15-thread-6": + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:51) + - waiting to lock <0x000000077b22b650> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) +"pool-15-thread-5": + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b650> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) +"pool-15-thread-2": + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b680> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) +"pool-15-thread-1": + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b7a0> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b680> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) +"pool-15-thread-3": + at org.itmo.Graph.lambda$parallelBFS$0(Graph.java:53) + - waiting to lock <0x000000077b22b770> (a java.util.concurrent.locks.ReentrantLock) + - locked <0x000000077b22b7a0> (a java.util.concurrent.locks.ReentrantLock) + at org.itmo.Graph$$Lambda$3/1915910607.call(Unknown Source) + at java.util.concurrent.FutureTask.run(FutureTask.java:266) + at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) + at java.lang.Thread.run(Thread.java:750) + +Found 1 deadlock. + diff --git a/tmp/results.txt b/tmp/results.txt index 027e7f9..3689cd6 100644 --- a/tmp/results.txt +++ b/tmp/results.txt @@ -1,32 +1,36 @@ Times for 10 vertices and 50 connections: Serial: 0 -Parallel: 0 +Parallel: 5 -------- Times for 100 vertices and 500 connections: Serial: 0 -Parallel: 0 +Parallel: 2 -------- Times for 1000 vertices and 5000 connections: -Serial: 1 -Parallel: 0 +Serial: 0 +Parallel: 3 -------- Times for 10000 vertices and 50000 connections: -Serial: 3 -Parallel: 0 +Serial: 7 +Parallel: 13 -------- Times for 10000 vertices and 100000 connections: -Serial: 2 -Parallel: 0 +Serial: 3 +Parallel: 19 -------- Times for 50000 vertices and 1000000 connections: -Serial: 30 -Parallel: 0 +Serial: 27 +Parallel: 11 -------- Times for 100000 vertices and 1000000 connections: -Serial: 18 -Parallel: 0 +Serial: 35 +Parallel: 32 -------- Times for 1000000 vertices and 10000000 connections: -Serial: 307 -Parallel: 0 +Serial: 1043 +Parallel: 146 +-------- +Times for 2000000 vertices and 10000000 connections: +Serial: 1996 +Parallel: 1220 -------- diff --git a/tmp/times.svg b/tmp/times.svg new file mode 100644 index 0000000..e4bcd94 --- /dev/null +++ b/tmp/times.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tmp/times.txt b/tmp/times.txt new file mode 100644 index 0000000..c5d63ea --- /dev/null +++ b/tmp/times.txt @@ -0,0 +1,38 @@ +100 100 6856322 +100 144 2018553 +100 196 1334527 +100 256 1190585 +100 324 1235842 +100 400 1785633 +1000 1600 1841157 +1000 3600 2257341 +1000 6400 2673595 +1000 10000 3382136 +1000 14400 2922859 +1000 19600 4962784 +1000 25600 5613775 +1000 32400 19526585 +1000 40000 1604325 +10000 40000 2309024 +10000 160000 2951564 +10000 360000 4126015 +10000 640000 4889242 +10000 1000000 6431268 +10000 1440000 18963525 +10000 1960000 10440579 +10000 2560000 13975598 +10000 3240000 13654956 +10000 4000000 15500303 +10000 40000 1785983 +10000 160000 2564154 +10000 360000 3416009 +10000 640000 5878264 +10000 1000000 6279153 +10000 1440000 8551860 +10000 1960000 10137957 +10000 2560000 11910459 +10000 3240000 12635761 +10000 4000000 13142321 +100000 4000000 26687625 +100000 16000000 63877639 +100000 36000000 123488881