I am looking for a way to pause a thread for accurate number of milliseconds in Java or C (I can use JNI to access the C method.
So far, I was using the following in java code.
LinkedBlockingQueue<String> SLEEPER = new LinkedBlockingQueue<String>();
SLEEPER.poll(msTime, TimeUnit.MILLISECONDS);
This was suggested on one of the threads in this forum and worked great on most of our windows7 machines.
But it is not giving me accrate results on a new set of hardware. So I decided to use JNI to access C. But even this does not pause for accurate amount of milliseconds on new hardwares (Dell and HP on Windows7).
JNIEXPORT void JNICALL Java_JniTimer_jniWait(JNIEnv *env, jobject obj , jint waitTime ) {
HANDLE hWaitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hWaitEvent)
{
WaitForSingleObject(hWaitEvent,waitTime);
CloseHandle (hWaitEvent);
}
}
Does anyone have a reliable option for accurate sleep on thread.
Thanks.
You can't do that on a non RT OS.
Not so much due to the resolution of timers, but because the per thread 'time slice' (sometimes referred to as quantum), is usually set to a few ms (15 on my antique xp here), and is not something you can just play with.
Related
Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds. I have tried to accomplish this by using the code below to try to run a function called wave() once a second for 30 seconds:
startTime = System.nanoTime();
wholeTime = System.nanoTime();
while (loop) {
if (startTime >= time2) {
startTime = System.nanoTime();
wave();
sec++;
}
if (sec == 30) {
loop = false;
endTime = System.nanoTime();
System.out.println(wholeTime - System.nanoTime());
}
}
}
This code did not work and am wondering why this code didn't work and if their is a better approach to the problem. Any ideas on how to improve fix the above code or other successful ways of accomplishing the problem are all welcome. Thank you for your help!
more simple:
long start=System.currentTimeMillis(); // Not very very accurate
while (System.currentTimeMillis()-start<30000)
{
wave();
// count something
}
You can use a Timer+TimerTask: https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html
http://bioportal.weizmann.ac.il/course/prog2/tutorial/essential/threads/timer.html
You may use Thread.sleep():
public static void main (String[] args) throws InterruptedException {
int count = 30;
long start = System.currentTimeMillis();
for(int i=0; i<count; i++) {
wave();
// how many milliseconds till the end of the second?
long sleep = start+(i+1)*1000-System.currentTimeMillis();
if(sleep > 0) // condition might be false if wave() runs longer than second
Thread.sleep(sleep);
}
}
Does anyone have a Fairly effective way of running a function repetitively in a precise and accurate number of milliseconds.
There is no way to do this kind of thing reliably and accurately in standard Java. The problem is that there is no way that you can guarantee that your thread will run when you want ti to run. For example:
your thread could be suspended to allow the GC to run
your thread could be preempted to allow another thread in your application to run
your thread could be suspended by the OS while it fetches pages by the JVM back from disk.
You can only get reliable behavior for this kind of code if you run on a hard realtime OS, and an realtime Java.
Note that this is not an issue with clock accuracy. The real problem is that the scheduler does not give you the kind of guarantees you need. For instance, none of the "sleep until X" functionality in a JVM can guarantee that your thread will wake up at time X exactly ... for any useful meaning of "exactly".
The other answers suggest various ways to do this, but beware that they are not (and cannot be) reliable and accurate in all circumstances .. or even on a typical machine running other things as well as your application.
I am running this test because I want to see the stacktrace of a program.
Below is my program:
public class NanoTime {
public static void main (String[] args) {
long StartTime = System.nanoTime();
StringBuffer buffer = new StringBuffer();
for(int i=0; i<1000; i++) {
buffer.append("a"); }
long EndTime = System.nanoTime();
long totalTime = EndTime-StartTime;
System.out.println("Total time of calculation ="+ totalTime);
}
}
Now I am using OpenJDK built with debug-level set to slowdebug and also another one set to fastdebug.
I get this output:
[New Thread 0x7ffff7fd3700 (LWP 22532)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fd3700 (LWP 22532)]0x00007fffe10002b4 in ?? ()
(gdb) bt
#0 0x00007fffe10002b4 in ?? ()
#1 0x0000000000000202 in ?? ()
#2 0x00007fffe1000160 in ?? ()
#3 0x00007ffff66bd1a9 in execute_internal_vm_tests () at /home/bionix/Openjdk8/hotspot/src/share/vm/prims/jni.cpp:5128
#4 0x00007ffff7fd2550 in ?? ()
#5 0x00007ffff6b08bf8 in VM_Version::get_cpu_info_wrapper () at /home/bionix/Openjdk8/hotspot/src/cpu/x86/vm/vm_version_x86.cpp:395
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
I am confused at the question marks there, as I expected native methods name.
Note: I am even disabling the JIT Compiler : gdb --args java -Xint Test
In ordinary code, gdb relies on debug information (and to a lesser extent the "linker" symbols) to find the names of functions as it unwinds. Debugging information is described in various standards, DWARF being the current best one for Linux. Compilers emit the debugging information that is then read by gdb.
For just-in-time compilers like OpenJDK, there is no agreed-upon solution to emitting debugging information for debuggers to read. And so, as you've found, gdb generally has no idea what is going on.
In fact, as you can see from your trace, gdb can't even really unwind the entire stack. That's what this means:
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Modern compilers and ABIs tend to require some extra debugging information to unwind as well -- and, again, there's no agreement on how this should work for JIT compilation. GDB has some heuristics it uses to try to unwind when this information isn't available, but as you can see, they sometimes fail.
So, that's the bad news.
The good news is that gdb provides some ways to write unwinders and debug info readers for JITs. And, someone is working on this for OpenJDK. I wasn't able to quickly find the source, but I did find this thread which explains it a little.
This is because jvm is using template interpreter. For that interpreter java bytecode handlers are translated into machine instructions for the current platform during start time. Still you can get the full stacktrace, more info: template interpreter demo
There is also cpp interpreter and that is the interpreter you would expect to see in your stacktraces. But cpp interpreter is not supported anymore and is only available with zero jvm variant.
Also there is an article about the interpreters.
What is the best way to make a Jni as fast as Possible?
I need to call a .dll for a conversation with a cxternal Measurement Box.
Atm i do call the values of the Box over a JNI with a static loaded Lib.
public class myJni{
static {
System.loadLibrary("myJniDll");
}
public native double Get4(String para);
}
very simple as you can see.
On C side i use:
HINSTANCE hInstLibrary = LoadLibrary("my_64.dll");
typedef void(*FunctionFunc)();
JNIEXPORT jdouble JNICALL my_Get4
(JNIEnv * penv, jclass clazz, jstring Para)
{
typedef double(__stdcall *Get4)(char FAR *lpszPara);
Get4 _Get4;
FunctionFunc _FunctionFunc2;
_Get4 = (Get4)GetProcAddress(hInstLibrary, "my_Get4");
_FunctionFunc2 = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");
const char *nativeString = penv->GetStringUTFChars(Para, 0);
const char* parameter = nativeString;
double ret = _Get4((char*)parameter);
penv->ReleaseStringUTFChars(Para, nativeString);
return ret;
}
The Code needs about 20 ms to get the Value of the Com Portunit. The Lag when the value is changing doesn't "feel" good. It is sensible when I change the value that it needs time to go over the Jni.
Has someone got some tweeks to get it to about 10 ms?
#Edit: Gil´s Pointer Skip made a huge impact. Its now less "laggy". Still not as far as i want to but ok.
The Unit on the Com port is a Measurement device that works in a 0.000000 accuracy. So the Lag is shown by the last 4 Numbers not smoothly changing but skipping much of the scale when changed.
You can skip loading the function pointer for each call:
static Get4 _Get4 = NULL;
static FunctionFunc _FunctionFunc2 = NULL;
if(!_Get4)
_Get4 = (Get4)GetProcAddress(hInstLibrary, "my_Get4");
if(!_FunctionFunc2)
_FunctionFunc2 = (FunctionFunc)GetProcAddress(hInstLibrary, "Function");
This will save a ot of time.
Other Answers offer some useful optimizations (viewed in isolation), but I'm pessimistic that they will give you the amount of speed-up that you desire.
If this method really takes 20 milliseconds per call, amortized over a number of calls, then I can confidently predict that the vast majority of that time is spent in either the call to Get4, or in the call to GetStringUTFChars. Neither of those can be optimized, so the chances of getting a 50% speedup are (IMO) non-existent.
You don't state which of these methods does anything resembling 'get the value of the Com Portunit', but you don't need to get the native function addresses every time you call this method. They won't change. Stick them into static variables the first time. As a matter of fact you don't need to dynamically load 'my_64.dll' at all. Statically link to it.
I am doing a past exam paper of Java, I am confused about one question listed below:
What would happen when a thread executes the following statement in its run() method? (Choose all that apply.)
sleep(500);
A. It is going to stop execution, and start executing exactly 500 milliseconds later.
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
C. It is going to result in a compiler error because you cannot call the sleep(…) method inside the run() method.
D. It is going to result in a compiler error because the sleep(…) method does not take any argument.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me? Many thanks.
I select A,B. but the key answer is only B, does there exist any circumstances that A could also happen? Could anyone please clarify that for me?
Yes, depending on your application, you certainly might get 500ms of sleep time and not a nanosecond more.
However, the reason why B is the better answer is that there are no guarantees about when any thread will be run again. You could have an application with a large number of CPU bound threads. Even though the slept thread is now able to be run, it might not get any cycles for a significant period of time. The precise sleep time also depends highly on the particulars of the OS thread scheduler and clock accuracy. Your application also may also have to compete with other applications on the same system which may delay its continued execution.
For example, this following program on my extremely fast 8xi7 CPU Macbook Pro shows a max-sleep of 604ms:
public class MaxSleep {
public static void main(String[] args) throws Exception {
final AtomicLong maxSleep = new AtomicLong(0);
ExecutorService threadPool = Executors.newCachedThreadPool();
// fork 1000 threads
for (int i = 0; i < 1000; i++) {
threadPool.submit(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
long total = 0;
// spin doing something that eats CPU
for (int j = 0; j < 10000000; j++) {
total += j;
}
// this IO is the real time sink though
System.out.println("total = " + total);
try {
long before = System.currentTimeMillis();
Thread.sleep(500);
long diff = System.currentTimeMillis() - before;
// update the max value
while (true) {
long max = maxSleep.get();
if (diff <= max) {
break;
}
if (maxSleep.compareAndSet(max, diff)) {
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
System.out.println("max sleep ms = " + maxSleep);
}
}
JVM cannot guarantee exactly 500 ms but it will start on or after ~500 ms as it will need to start its 'engine' back considering no other threads are blocking any resources which may delay a bit.
Read: Inside the Hotspot VM: Clocks, Timers and Scheduling Events
Edit: As Gray pointed out in the comment - the scheduling with other threads also a factor, swapping from one to another may cost some time.
According to Javadoc:-
Sleep()
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
So it may be ~500ms
B. It is going to stop execution, and start executing again not earlier than 500 milliseconds later.
Looks more prominent.
As you know that there are two very closely-related states in Thread : Running and Runnable.
Running : means currently executing thread. Its execution is currently going on.
Runnable : means thread is ready to get processed or executed. But is waiting to be picked up by Thread Schedular. Now this thread schedular, as per its own wish/defined algorithm depending upon the JVM(for example, slicing algorithm) will pick up one of the available/Runnable threads to process them.
So whenever you call sleep method, it only guarantees that the execution of the code by the thread which it ran on, is paused for the specified milliseconds in the argument(e.g. 300ms in threadRef.sleep(300);). As soon as the time defined goes by, it comes back to Runnable state(means back to Available State to be picked up by Thread Schedular).
Therefore, there is no guarantee that your remaining code will start getting executed immediately after sleep method completion.
These sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS. Option B: Not earlier than 500 is more correct.
You cannot select A and B as they are opposite to each other, the main difference: exactly 500 milliseconds later and not earlier than 500 milliseconds later
first mean exactly what it means (500 milliseconds only), second means that it can sleep 501 or 502 or even 50000000000000
next question - why B is true, it is not so simply question, you need to understand what is the different between hard-realtime and soft-realtime, and explaining of all reasons is quite offtopic, so simply answer - because of many technical reasons java cannot guarantee hard real time execution of your code, this is why it stated that sleep will finish not earlier than ...
you can read about thread scheduling, priorities, garbage collection, preemptive multitasking - all these are related to this
Myself and another developer on my time recently moved from a Core 2 Duo machine at work to a new Core 2 Quad 9505; both running Windows XP SP3 32-bit with JDK 1.6.0_18.
Upon doing so, a couple of our automated unit tests for some timing/statistics/metrics aggregation code promptly started failing, due to what appear to be ridiculous values coming back from System.nanoTime().
Test code that shows this behaviour, reliably, on my machine is:
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Test;
public class NanoTest {
#Test
public void testNanoTime() throws InterruptedException {
final long sleepMillis = 5000;
long nanosBefore = System.nanoTime();
long millisBefore = System.currentTimeMillis();
Thread.sleep(sleepMillis);
long nanosTaken = System.nanoTime() - nanosBefore;
long millisTaken = System.currentTimeMillis() - millisBefore;
System.out.println("nanosTaken="+nanosTaken);
System.out.println("millisTaken="+millisTaken);
// Check it slept within 10% of requested time
assertThat((double)millisTaken, Matchers.closeTo(sleepMillis, sleepMillis * 0.1));
assertThat((double)nanosTaken, Matchers.closeTo(sleepMillis * 1000000, sleepMillis * 1000000 * 0.1));
}
}
Typical output:
millisTaken=5001
nanosTaken=2243785148
Running it 100x yields nano results between 33% and 60% of the actual sleep time; usually around 40% though.
I understand the weaknesses in accuracy of timers in Windows, and have read related threads like Is System.nanoTime() consistent across threads?, however my understanding is that System.nanoTime() is intended for exactly the purpose we're using it :- measuring elapsed time; more accurately than currentTimeMillis().
Does anyone know why it's returning such crazy results? Is this likely to be a hardware architecture problem (the only major thing that has changed is the CPU/Motherboard on this machine)? A problem with the Windows HAL with my current hardware? A JDK problem? Should I abandon nanoTime()? Should I log a bug somewhere, or any suggestions on how I could investigate further?
UPDATE 19/07 03:15 UTC: After trying finnw's test case below I did some more Googling, coming across entries such as bugid:6440250. It also reminded me of some other strange behaviour I noticed late Friday where pings were coming back negative. So I added /usepmtimer to my boot.ini and now all the tests behave as expected., and my pings are normal too.
I'm a bit confused about why this was still an issue though; from my reading I thought TSC vs PMT issues were largely resolved in Windows XP SP3. Could it be because my machine was originally SP2, and was patched to SP3 rather than installed originally as SP3? I now also wonder whether I should be installing patches like the one at MS KB896256. Maybe I should take this up with the corporate desktop build team?
The problem was resolved (with some open suspicions about the suitability of nanoTime() on multi-core systems!) by adding /usepmtimer to the end of my C:\boot.ini string; forcing Windows to use the Power Management timer rather than the TSC. It's an open question as to why I needed to do this given I'm on XP SP3, as I understood that this was the default, however perhaps it was due to the manner in which my machine was patched to SP3.
On my system (Windows 7 64-Bit, Core i7 980X):
nanosTaken=4999902563
millisTaken=5001
System.nanoTime() uses OS-specific calls, so I expect that you are seeing a bug in your Windows/processor combination.
You probably want to read the answers to this other stack overflow question: Is System.nanoTime() completely useless?.
In summary, it would appear that nanoTime relies on operating system timers that may be affected by the presence of multiple core CPUs. As such, nanoTime may not be that useful on certain combinations of OS and CPU, and care should be taken when using it in portable Java code that you intend to run on multiple target platforms. There seems to be a lot of complaining on the web on this subject, but not much consensus on a meaningful alternative.
It is difficult to tell whether this is a bug or just normal timer variation between cores.
An experiment you could try is to use native calls to force the thread to run on a specific core.
Also, to rule out power management effects, try spinning in a loop as an alternative to sleep():
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.W32API;
public class AffinityTest {
private static void testNanoTime(boolean sameCore, boolean spin)
throws InterruptedException {
W32API.HANDLE hThread = kernel.GetCurrentThread();
final long sleepMillis = 5000;
kernel.SetThreadAffinityMask(hThread, new NativeLong(1L));
Thread.yield();
long nanosBefore = System.nanoTime();
long millisBefore = System.currentTimeMillis();
kernel.SetThreadAffinityMask(hThread, new NativeLong(sameCore? 1L: 2L));
if (spin) {
Thread.yield();
while (System.currentTimeMillis() - millisBefore < sleepMillis)
;
} else {
Thread.sleep(sleepMillis);
}
long nanosTaken = System.nanoTime() - nanosBefore;
long millisTaken = System.currentTimeMillis() - millisBefore;
System.out.println("nanosTaken="+nanosTaken);
System.out.println("millisTaken="+millisTaken);
}
public static void main(String[] args) throws InterruptedException {
System.out.println("Sleeping, different cores");
testNanoTime(false, false);
System.out.println("\nSleeping, same core");
testNanoTime(true, false);
System.out.println("\nSpinning, different cores");
testNanoTime(false, true);
System.out.println("\nSpinning, same core");
testNanoTime(true, true);
}
private static final Kernel32Ex kernel =
(Kernel32Ex) Native.loadLibrary(Kernel32Ex.class);
}
interface Kernel32Ex extends Kernel32 {
NativeLong SetThreadAffinityMask(HANDLE hThread, NativeLong dwAffinityMask);
}
If you get very different results depending on core selection (e.g. 5000ms on the same core but 2200ms on different cores) that would suggest that the problem is just natural timer variation between cores.
If you get very different results from sleeping vs. spinning, it is more likely due to power management slowing down the clocks.
If none of the four results are close to 5000ms, then it might be a bug.