Hi,
ich bin mir nicht sicher ob ich einen Fehler im Programm habe oder ob ich bloß eine Optimierungsstrategie übersehe:
Output:
Das stimmt doch so nicht? Wiese benötigt der parallel ausgeführte Code praktisch keine Zeit?
ich bin mir nicht sicher ob ich einen Fehler im Programm habe oder ob ich bloß eine Optimierungsstrategie übersehe:
Java:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class ArraySummer {
public static void main(final String[] args) {
final int[] array = new int[200000000];
final Random r = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = Math.abs(r.nextInt() / 2);
}
for (int i = 0; i < 20; ++i) {
parallSummer(array);
sequentiellSummer(array);
}
System.out.println("start");
for (int i = 0; i < 10; ++i) {
testPar(array);
testSeq(array);
System.out.println();
}
}
final static void testSeq(final int[] array) {
final long s = System.nanoTime();
sequentiellSummer(array);
System.out.println("s:" + (System.nanoTime() - s) / 1e6 + "ms");
}
final static void testPar(final int[] array) {
final long s = System.nanoTime();
parallSummer(array);
System.out.println("p:" + (System.nanoTime() - s) / 1e6 + "ms");
}
public static void sequentiellSummer(final int[] array) {
new SeqSummer(array).calc();
}
public static void parallSummer(final int[] array) {
final int processors = 2; // Runtime.getRuntime().availableProcessors();
final List<Long> longs = new ArrayList<Long>();
final Runnable merger = new Runnable() {
@Override
public void run() {
calc();
}
long calc() {
long sum = 0;
for (final long i : longs) {
sum += i;
}
return sum;
}
};
final CyclicBarrier barrier = new CyclicBarrier(processors, merger);
for (int part = 0; part < processors; part++) {
new Thread(new AtomarSummer(barrier, array, processors, part, longs)).start();
}
}
}
class SeqSummer {
private final int[] array;
public SeqSummer(final int[] array) {
this.array = array;
}
public long calc() {
long sum = 0;
for (int i = 0; i < array.length; ++i) {
sum += array[i];
}
return sum;
}
}
class AtomarSummer implements Runnable {
private final CyclicBarrier barrier;
private final int[] array;
private final List<Long> longs;
private final int start, end;
public AtomarSummer(final CyclicBarrier barrier, final int[] array, final int maxPart,
final int currentPart, final List<Long> longs) {
this.barrier = barrier;
this.array = array;
this.longs = longs;
start = (int) ((double) array.length / maxPart * currentPart);
end = (int) ((double) array.length / maxPart * (currentPart + 1) - 1);
}
@Override
public void run() {
long sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
longs.add(sum);
try {
barrier.await();
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (final BrokenBarrierException e) {
e.printStackTrace();
}
}
}
Output:
start
p:0.942543ms
s:378.924406ms
p:0.173262ms
s:322.728754ms
p:2.065446ms
s:320.918554ms
p:0.209188ms
s:292.466057ms
p:6.518078ms
s:343.991192ms
p:0.228163ms
s:332.049146ms
p:0.197921ms
s:330.990676ms
p:0.17808ms
s:325.774824ms
p:0.230276ms
s:325.778092ms
p:0.216491ms
s:362.563178ms
Das stimmt doch so nicht? Wiese benötigt der parallel ausgeführte Code praktisch keine Zeit?