I wanted to learn parallel programming for speeding up algorithms and chose Java.
I wrote two functions for summing long
integers in array - one simple iterating through array, second - dividing array to parts and sum up parts in separated threads.
I expected to be logical a roughly 2x speed up using two threads. However, what I've got is only 24% speed up. Moreover, using more threads, I don't get any improvement (maybe less 1%) over two threads. I know that there should be thread creation/joining overhead, but I guess it shouldn't be that big.
Can you please explain, what I'm missing or where is error in code? Here is code:
import java.util.concurrent.ThreadLocalRandom;
public class ParallelTest {
public static long sum1 (long[] num, int a, int b) {
long r = 0;
while (a < b) {
r += num[a];
++a;
}
return r;
}
public static class SumThread extends Thread {
private long num[];
private long r;
private int a, b;
public SumThread (long[] num, int a, int b) {
super();
this.num = num;
this.a = a;
this.b = b;
}
@Override
public void run () {
r = ParallelTest.sum1(num, a, b);
}
public long getSum () {
return r;
}
}
public static long sum2 (long[] num, int a, int b, int threadCnt) throws InterruptedException {
SumThread[] th = new SumThread[threadCnt];
int i = 0, c = (b - a + threadCnt - 1) / threadCnt;
for (;;) {
int a2 = a + c;
if (a2 > b) {
a2 = b;
}
th[i] = new SumThread(num, a, a2);
th[i].start();
if (a2 == b) {
break;
}
a = a2;
++i;
}
for (i = 0; i < threadCnt; ++i) {
th[i].join();
}
long r = 0;
for (i = 0; i < threadCnt; ++i) {
r += th[i].getSum();
}
return r;
}
public static void main(String[] args) throws InterruptedException {
final int N = 230000000;
long[] num = new long[N];
for (int i = 0; i < N; ++i) {
num[i] = ThreadLocalRandom.current().nextLong(1, 9999);
}
// System.out.println(Runtime.getRuntime().availableProcessors());
long timestamp = System.nanoTime();
System.out.println(sum1(num, 0, num.length));
System.out.println(System.nanoTime() - timestamp);
for (int n = 2; n <= 4; ++n) {
timestamp = System.nanoTime();
System.out.println(sum2(num, 0, num.length, n));
System.out.println(System.nanoTime() - timestamp);
}
}
}
EDIT: I have i7 processor with 4 cores (8 threads). Output given by code is:
1149914787860
175689196
1149914787860
149224086
1149914787860
147709988
1149914787860
138243999
If you're unsatisfied with the processing output of your computer, it might be time to hyper-thread your central processing unit's (CPU) cores. Hyper-threading can be a great way to improve the processing speed of your PC without having to go through a major hardware makeover.
What Is Multithreading Used For? The main reason for incorporating threads into an application is to improve its performance. Performance can be expressed in multiple ways: A web server will utilize multiple threads to simultaneous process requests for data at the same time.
Disadvantages. Depending on the design and architecture of the processor, simultaneous multithreading can decrease performance if any of the shared resources are bottlenecks for performance.
The program is probably main memory bandwidth limited with just two threads, as it's a small loop, that fetches data almost as fast as ram can supply data to the processor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With