Finding execution time for multicore code in Java - java

I'm attempting to find the difference in running time between multi and single core solutions in Java. So far, the single core runs fine. However, I'm getting erratic reports from the multicore solution, some reporting that it took 0 nanoseconds, or slightly more.
The multicore reads as follow: (Notice that I'm not doing anything too advanced, just trying to find the length of time it ran. CPU execution time in Java convinced me to use System.nanoTime() instead of .currentTimeMillis() )
long start = System.nanoTime();
Runnable r0 = new FindMagicBrute(n);
Thread t0 = new Thread(r0);
Thread t1 = new Thread(r0);
Thread t2 = new Thread(r0);
t0.start();
t1.start();
t2.start();
long end = System.nanoTime();
System.out.println("Multithreaded run ended in " + (end-start) + " nanoseconds.");
Is there a way to determine when a thread has stopped executing?

You should wait for the threads to finish by calling join on each of them.
Otherwise, you're not timing anything but the time it takes to create the threads.

Related

Join a group of threads with overall timeout

Is there a way to join a group of threads simultaneously with an overall timeout?
Suppose we have Collection<Thread> threads; and int timeout;. If I didn't care about the timeout, I would do
for (Thread t : threads)
t.join();
but I want to wait until either all threads are done, or a certain amount of time passes, whichever comes first. I was searching for a (hypothetical) ThreadGroup.join(int) which would do this.
Note that what I'm asking for is different from doing
for (Thread t : threads)
t.join(timeout);
Rather, I'm looking for something less verbose (and perhaps more reliable) than
int timeout = 10000;
for (Thread t : threads) {
if (timeout <= 0) break;
long start = System.currentTimeMillis();
t.join(timeout);
long end = System.currentTimeMillis();
// substract time elapsed from next timeout:
timeout -= (int) (end - start);
}
First create a single CountDownLatch having a count for every thread in the group.
A controlling thread can await(timeout, TimeUnit) on the latch.
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CountDownLatch.html#await-long-java.util.concurrent.TimeUnit-
Start the threads that are in the group.
Each of the threads in the group should decrement the latch when it completes.
The controlling thread will wait until everything in the group has completed or the timeout happens, and because await returns a boolean, the controlling thread can tell whether the latch was decremented naturally or whether a timeout occurred.

Threads run in serial not parallel

I am trying to learn concurrency in Java, but whatever I do, 2 threads run in serial, not parallel, so I am not able to replicate common concurrency issues explained in tutorials (like thread interference and memory consistency errors). Sample code:
public class Synchronization {
static int v;
public static void main(String[] args) {
Runnable r0 = () -> {
for (int i = 0; i < 10; i++) {
Synchronization.v++;
System.out.println(v);
}
};
Runnable r1 = () -> {
for (int i = 0; i < 10; i++) {
Synchronization.v--;
System.out.println(v);
}
};
Thread t0 = new Thread(r0);
Thread t1 = new Thread(r1);
t0.start();
t1.start();
}
}
This always give me a result starting from 1 and ending with 0 (whatever the loop length is). For example, the code above gives me every time:
1
2
3
4
5
6
7
8
9
10
9
8
7
6
5
4
3
2
1
0
Sometimes, the second thread starts first and the results are the same but negative, so it is still running in serial.
Tried in both Intellij and Eclipse with identical results. CPU has 2 cores if it matters.
UPDATE: it finally became reproducible with huge loops (starting from 1_000_000), though still not every time and just with small amount of final discrepancy. Also seems like making operations in loops "heavier", like printing thread name makes it more reproducible as well. Manually adding sleep to thread also works, but it makes experiment less cleaner, so to say. The reason doesn't seems to be that first loop finishes before the second starts, because I see both loops printing to console while continuing operating and still giving me 0 at the end. The reasons seems more like a thread race for same variable. I will dig deeper into that, thanks.
Seems like first started thread just never give a chance to second in Thread Race to take a variable/second one just never have a time to even start (couldn't say for sure), so the second almost* always will be waiting until first loop will be finished.
Some heavy operation will mix the result:
TimeUnit.MILLISECONDS.sleep(100);
*it is not always true, but you are was lucky in your tests
Starting a thread is heavyweight operation, meaning that it will take some time to perform. Due that fact, by the time you start second thread, first is finished.
The reasoning why sometimes it is in "revert order" is due how thread scheduler works. By the specs there are not guarantees about thread execution order - having that in mind, we know that it is possible for second thread to run first (and finish)
Increase iteration count to something meaningful like 10000 and see what will happen then.
This is called lucky timing as per Brian Goetz (Author of Java Concurrency In Practice). Since there is no synchronization to the static variable v it is clear that this class is not thread-safe.

Java - System.out effect on performance

I've seen this question and it's somewhat similar. I would like to know if it really is a big factor that would affect the performance of my application. Here's my scenario.
I have this Java webapp that can upload thousands of data from a Spreadsheet which is being read per row from top to bottom. I'm using System.out.println() to show on the server's side on what line the application is currently reading.
- I'm aware of creating a log file. In fact, I'm creating a log file and at the same time, displaying the logs on the server's prompt.
Is there any other way of printing the current data on the prompt?
I was recently testing with (reading and) writing large (1-1.5gb) text-files, and I found out that:
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(java.io.FileDescriptor.out), "UTF-8"), 512));
out.println(yourString);
//...
out.flush();
is in fact almost 250% faster than
System.out.println(yourString);
My test-program first read about 1gb of data, processed it a bit and outputted it in slightly different format.
Test results (on Macbook Pro, with SSD reading&writing using same disk):
data-output-to-system-out > output.txt => 1min32sec
data-written-to-file-in-java => 37sec
data-written-to-buffered-writer-stdout > output.txt => 36sec
I did try with multiple buffer sized between 256-10k but that didn't seem to matter.
So keep in mind if you're creating unix command-line tools with Java where output is meant to be directed or piped to somewhere else, don't use System.out directly!
It can have an impact on your application performance. The magnitude will vary depending on the kind of hardware you are running on and the load on the host.
Some points on which this can translate to performance wise:
-> Like Rocket boy stated, println is synchronized, which means you will be incurring in locking overhead on the object header and may cause thread bottlenecks depending on your design.
-> Printing on the console requires kernel time, kernel time means the cpu will not be running on user mode which basically means your cpu will be busy executing on kernel code instead of your application code.
-> If you are already logging this, that means extra kernel time for I/O, and if your platform does not support asynchronous I/O this means your cpu might become stalled on busy waits.
You can actually try and benchmark this and verify this yourself.
There are ways to getaway with this like for example having a really fast I/O, a huge machine for dedicated use maybe and biased locking on your JVM options if your application design will not be multithreaded on that console printing.
Like everything on performance, it all depends on your hardware and priorities.
System.out.println()
is synchronized.
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
If multiple threads write to it, its performance will suffer.
Yes, it will have a HUGE impact on performance. If you want a quantifiable number, well then there's plenty of software and/or ways of measuring your own code's performance.
System.out.println is very slow compared to most slow operations. This is because it places more work on the machine than other IO operations (and it is single threaded)
I suggest you write the output to a file and tail the output of this file. This way, the output will still be slow, but it won't slow down your web service so much.
Here's a very simple program to check performance of System.out.println and compare it with multiplication operation (You can use other operations or function specific to your requirements).
public class Main{
public static void main(String []args) throws InterruptedException{
long tTime = System.nanoTime();
long a = 123L;
long b = 234L;
long c = a*b;
long uTime = System.nanoTime();
System.out.println("a * b = "+ c +". Time taken for multiplication = "+ (uTime - tTime) + " nano Seconds");
long vTime = System.nanoTime();
System.out.println("Time taken to execute Print statement : "+ (vTime - uTime) + " nano Seconds");
}
}
Output depends on your machine and it's current state.
Here's what I got on : https://www.onlinegdb.com/online_java_compiler
a * b = 28782. Time taken for multiplication = 330 nano Seconds
Time taken to execute Print statement : 338650 nano Seconds
EDIT :
I have logger set up on my local machine so wanted to give you idea of performance difference between system.out.println and logger.info - i.e., performance comparison between console print vs logging
public static void main(String []args) throws InterruptedException{
long tTime = System.nanoTime();
long a = 123L;
long b = 234L;
long c = a*b;
long uTime = System.nanoTime();
System.out.println("a * b = "+ c +". Time taken for multiplication = "+ (uTime - tTime) + " nano Seconds");
long vTime = System.nanoTime();
System.out.println("Time taken to execute Print statement : "+ (vTime - uTime) + " nano Seconds");
long wTime = System.nanoTime();
logger.info("a * b = "+ c +". Time taken for multiplication = "+ (uTime - tTime) + " nano Seconds");
long xTime = System.nanoTime();
System.out.println("Time taken to execute log statement : "+ (xTime - wTime) + " nano Seconds");
}
Here's what I got on my local machine :
a * b = 28782. Time taken for multiplication = 1667 nano Seconds
Time taken to execute Print statement : 34080917 nano Seconds
2022-11-15 11:36:32.734 [] INFO CreditAcSvcImpl uuid: - a * b = 28782. Time taken for multiplication = 1667 nano Seconds
Time taken to execute log statement : 9645083 nano Seconds
Notice that system.out.println is taking almost 24 ms higher then the logger.info.

What really is to “warm up” threads on multithreading processing?

I’m dealing with multithreading in Java and, as someone pointed out to me, I noticed that threads warm up, it is, they get faster as they are repeatedly executed. I would like to understand why this happens and if it is related to Java itself or whether it is a common behavior of every multithreaded program.
The code (by Peter Lawrey) that exemplifies it is the following:
for (int i = 0; i < 20; i++) {
ExecutorService es = Executors.newFixedThreadPool(1);
final double[] d = new double[4 * 1024];
Arrays.fill(d, 1);
final double[] d2 = new double[4 * 1024];
es.submit(new Runnable() {
#Override
public void run() {
// nothing.
}
}).get();
long start = System.nanoTime();
es.submit(new Runnable() {
#Override
public void run() {
synchronized (d) {
System.arraycopy(d, 0, d2, 0, d.length);
}
}
});
es.shutdown();
es.awaitTermination(10, TimeUnit.SECONDS);
// get a the values in d2.
for (double x : d2) ;
long time = System.nanoTime() - start;
System.out.printf("Time to pass %,d doubles to another thread and back was %,d ns.%n", d.length, time);
}
Results:
Time to pass 4,096 doubles to another thread and back was 1,098,045 ns.
Time to pass 4,096 doubles to another thread and back was 171,949 ns.
... deleted ...
Time to pass 4,096 doubles to another thread and back was 50,566 ns.
Time to pass 4,096 doubles to another thread and back was 49,937 ns.
I.e. it gets faster and stabilises around 50 ns. Why is that?
If I run this code (20 repetitions), then execute something else (lets say postprocessing of the previous results and preparation for another mulithreading round) and later execute the same Runnable on the same ThreadPool for another 20 repetitions, it will be warmed up already, in any case?
On my program, I execute the Runnable in just one thread (actually one per processing core I have, its a CPU-intensive program), then some other serial processing alternately for many times. It doesn’t seem to get faster as the program goes. Maybe I could find a way to warm it up…
It isn't the threads that are warming up so much as the JVM.
The JVM has what's called JIT (Just In Time) compiling. As the program is running, it analyzes what's happening in the program and optimizes it on the fly. It does this by taking the byte code that the JVM runs and converting it to native code that runs faster. It can do this in a way that is optimal for your current situation, as it does this by analyzing the actual runtime behavior. This can (not always) result in great optimization. Even more so than some programs that are compiled to native code without such knowledge.
You can read a bit more at http://en.wikipedia.org/wiki/Just-in-time_compilation
You could get a similar effect on any program as code is loaded into the CPU caches, but I believe this will be a smaller difference.
The only reasons I see that a thread execution can end up being faster are:
The memory manager can reuse already allocated object space (e.g., to let heap allocations fill up the available memory until the max memory is reached - the Xmx property)
The working set is available in the hardware cache
Repeating operations might create operations the compiler can easier reorder to optimize execution

Will this pause my Java thread for a minute?

Am I doing something really stupid here? I am trying to execute a method every minute or so, forever, or until I stop the program.
while(true) {
this.doSomethingPeriodically();
Calendar now = Calendar.getInstance();
int minutes = now.get(Calendar.MINUTE);
int resume = minutes + 1;
while (now.get(Calendar.MINUTE) < resume) {
// waiting for a minute
}
}
This code will never leave the loop. It's an endless loop, since the Calendar instance refered to by now won't change.
Also, what you try to do here is implement busy waiting which is a very bad idea (it uses CPU time doing nothing interesting).
The correct way to sleep is to use Thread.sleep().
the simplest way for execute tasks repeteadly in java is the java.util.TimerTask and java.util.Timer api.
A simple code is:
public class PrinterTimerTask extends java.util.TimerTask {
#Override
public void run() {
System.out.println( 'Current time is: ' + System.nanoTime() );
}
public static void main(String[] args) {
long delay = 0;
long period = 60000;
java.util.Timer timer = new java.util.Timer(threadName);
PrinterTimerTask task = new PrinterTimerTask();
timer = new Timer("SomeThreadNameForProfiler");
timer.schedule( task, delay, period );
}
}
Variables:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
period - time in milliseconds between successive task executions.
More info:
Timer and TimerTask javadoc:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TimerTask.html
Another example:
http://www.javapractices.com/topic/TopicAction.do?Id=54
[]'s,
And Past
Try using the Timer class instead. It's meant for this sort of thing:
http://www.javapractices.com/topic/TopicAction.do?Id=54
https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Edit:
I just read that there's a newer replacement for Timer: ExecutorService. I've never used it, but it seems to have some advantages:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html
Java Timer vs ExecutorService?
Try using sleep instead, as it won't cause the processor to continue working on the thread:
Thread.sleep()
while(true) {
this.doSomethingPeriodically();
Thread.sleep(60000);
}
It would be better to use a Timer or at least use a sleep.
What you're trying to do here is called busy waiting. You are unnecessarily using huge amounts of CPU time (and you would even be using unnecessary memory if you fixed your bug and created a new Calendar instance in each loop).
What you actually want is the method Thread.sleep(), it is pretty well explained in a tutorial on sun.com.
It's better to use the sleep function: CurrentThread.sleep() and you specify the number of milliseconds that you want as a delay. It's better than busy waiting...

Categories

Resources