Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum of range multithreading

My program is trying to sum a range with a given number of threads in order to run it in parallel but it seems that with just one threads it runs better than 4 (I have an 8 core CPU). It is my first time working with multithreading in Java so maybe I have a problem in my code that makes it take longer?

My benchmarks(sum of range 0-10000) done for the moment are:

1 thread: 1350 microsecs (average) 2 thread: 1800 microsecs (average) 4 thread: 2400 microsecs (average) 8 thread: 3300 microsecs (average)

Thanks in advance!

/*
Compile: javac RangeSum.java
Execute: java RangeSum nThreads initRange finRange
*/

import java.util.ArrayList;
import java.util.concurrent.*;

public class RangeSum implements Runnable {

private int init;
private int end; 
private int id;
static public int out = 0;

Object lock = new Object();

public synchronized static void increment(int partial) {
    out = out + partial;
}

public RangeSum(int init,int end) { 
    this.init = init;
    this.end = end;
}//parameters to pass in threads

// the function called for each thread
public void run() {
    int partial = 0;

    for(int k = this.init; k < this.end; k++)
    {
        partial = k + partial + 1;
    }
    increment(partial);
}//thread: sum its id to the out variable

public static void main(String args[]) throws InterruptedException {
    final long startTime = System.nanoTime()/1000;//start time: microsecs

    //get command line values for
    int NumberOfThreads = Integer.valueOf(args[0]);
    int initRange = Integer.valueOf(args[1]);
    int finRange = Integer.valueOf(args[2]);
    //int[] out = new int[NumberOfThreads];

    // an array of threads
    ArrayList<Thread> Threads = new ArrayList<Thread>(NumberOfThreads);

    // spawn the threads / CREATE
    for (int i = 0; i < NumberOfThreads; i++) {
        int initial = i*finRange/NumberOfThreads;
        int end = (i+1)*finRange/NumberOfThreads;
        Threads.add(i, new Thread(new RangeSum(initial,end)));
        Threads.get(i).start();
    }

    // wait for the threads to finish / JOIN
    for (int i = 0; i < NumberOfThreads; i++) {
        try {
            Threads.get(i).join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    System.out.println("All threads finished!");

    System.out.println("Total range sum: " + out);

    final long endTime = System.nanoTime()/1000;//end time
    System.out.println("Time elapsed: "+(endTime - startTime));
}
}
like image 901
Sergi Olives Orfila Avatar asked Feb 23 '26 14:02

Sergi Olives Orfila


1 Answers

Your workload entirely in memory-non-blocking computation - on a general principle, in this kind of scenario, a single thread will complete the work faster than multiple threads.

Multiple threads tend to interfere with the L1/L2 CPU caching and incur additional overhead for context switching

Specifically, wrt to your code, you initialize final long startTime = System.nanoTime()/1000; too early and measure thread setup time as well as the actual time it takes them to complete. Its probably better to setup your Threads list first and then:

final long startTime =...
for (int i = 0; i < NumberOfThreads; i++) {
    Thread.get(i).start()
}

but really, in this case, the expectations that multiple threads will improve processing time is not warranted.

like image 155
David Soroko Avatar answered Feb 25 '26 04:02

David Soroko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!