lab7
This commit is contained in:
@@ -1,11 +1,8 @@
|
|||||||
package ru.lionarius;
|
package ru.lionarius;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
@@ -107,24 +104,75 @@ public class IntegralCalculator {
|
|||||||
|
|
||||||
this.callProgressCallback(0, n);
|
this.callProgressCallback(0, n);
|
||||||
|
|
||||||
|
var remainder = n % parallelism;
|
||||||
|
var partitionSize = n / parallelism;
|
||||||
|
var currentStart = 0L;
|
||||||
|
|
||||||
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
|
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
|
||||||
|
|
||||||
final var futures = new ArrayList<Future<Double>>();
|
final var futures = new ArrayList<Future<Double>>();
|
||||||
|
final var semaphore = new Semaphore(2);
|
||||||
|
final var lock = new ReentrantLock();
|
||||||
|
final var latch = new CountDownLatch(parallelism);
|
||||||
|
|
||||||
|
var times = new long[parallelism];
|
||||||
|
var totalProgress = new long[]{0L};
|
||||||
for (var i = 0; i < parallelism; i++) {
|
for (var i = 0; i < parallelism; i++) {
|
||||||
final var order = i;
|
final var start = currentStart;
|
||||||
|
final var end = currentStart + partitionSize + (remainder > 0 ? 1 : 0);
|
||||||
|
if (remainder > 0)
|
||||||
|
remainder--;
|
||||||
|
currentStart = end;
|
||||||
|
|
||||||
|
final var innerI = i;
|
||||||
|
|
||||||
futures.add(executor.submit(() -> {
|
futures.add(executor.submit(() -> {
|
||||||
var partitionSum = 0.0;
|
var partitionSum = 0.0;
|
||||||
for (var j = order; j < n; j += parallelism) {
|
try {
|
||||||
partitionSum += function.apply(lowerBound + h * j);
|
semaphore.acquire();
|
||||||
|
|
||||||
this.callProgressCallback(j, n);
|
for (var j = start; j < end; j++) {
|
||||||
|
partitionSum += function.apply(lowerBound + h * j);
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
totalProgress[0] += 1;
|
||||||
|
this.callProgressCallback(totalProgress[0], n);
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.lock();
|
||||||
|
try {
|
||||||
|
times[innerI] = System.nanoTime();
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
semaphore.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
latch.countDown();
|
||||||
|
|
||||||
return partitionSum;
|
return partitionSum;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
latch.await();
|
||||||
|
|
||||||
for (var future : futures) {
|
for (var future : futures) {
|
||||||
sum += future.get();
|
sum += future.resultNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
var minimumTime = Long.MAX_VALUE;
|
||||||
|
for (var time : times) {
|
||||||
|
if (time < minimumTime)
|
||||||
|
minimumTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < parallelism; i++) {
|
||||||
|
System.out.printf("Thread %d took %.6fms%n", i, (times[i] - minimumTime) / 1_000_000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sum *= h;
|
sum *= h;
|
||||||
|
|||||||
@@ -9,25 +9,28 @@ public class Main {
|
|||||||
Function<Double, Double> function = x -> Math.sin(x) * x;
|
Function<Double, Double> function = x -> Math.sin(x) * x;
|
||||||
var lowerBound = 0.0;
|
var lowerBound = 0.0;
|
||||||
var upperBound = 1.0;
|
var upperBound = 1.0;
|
||||||
double[] accuracies = {0.0001, 0.00001, 0.0000001, 0.000000001, 0.000000001};
|
double[] accuracies = {0.0001, 0.00001, 0.0000001, 0.000000005};
|
||||||
|
|
||||||
var executor = Executors.newCachedThreadPool();
|
var executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
for (final var accuracy : accuracies) {
|
for (final var accuracy : accuracies) {
|
||||||
var calculator = new IntegralCalculator(
|
var calculator = new IntegralCalculator(
|
||||||
accuracy
|
accuracy,
|
||||||
|
(i, n) -> {
|
||||||
|
if (i % (n / 15) == 0)
|
||||||
|
System.out.printf("[%s] Progress %f%%%n", Thread.currentThread().getName(), i / (double) n * 100.0);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var startTime = System.nanoTime();
|
var startTime = System.nanoTime();
|
||||||
|
|
||||||
double value = 0;
|
double value = 0;
|
||||||
try {
|
try {
|
||||||
value = calculator.calculate(function, lowerBound, upperBound, executor, 1);
|
value = calculator.calculate(function, lowerBound, upperBound, executor, 8);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
System.err.println("Error calculating integral: " + e.getMessage());
|
System.err.println("Error calculating integral: " + e.getMessage());
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
System.err.println("Thread interrupted: " + e.getMessage());
|
System.err.println("Thread interrupted: " + e.getMessage());
|
||||||
executor.shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var totalTime = System.nanoTime() - startTime;
|
var totalTime = System.nanoTime() - startTime;
|
||||||
|
|||||||
Reference in New Issue
Block a user