Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java multiple threads give very small perfomance gain

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
like image 214
Somnium Avatar asked Dec 11 '16 15:12

Somnium


People also ask

Does more threads increase performance?

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.

Does multithreading improve performance Java?

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.

Can multithreading decrease performance?

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.


1 Answers

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.

like image 149
rcgldr Avatar answered Nov 02 '22 06:11

rcgldr