 |
AppletTalk.com Java discussions newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Lapo Guest
|
Posted: Sun Dec 28, 2003 3:39 am Post subject: System.currentTimeMillis, il RDTSC e mio primo incontro col |
|
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Ciao a tutti,
~ non sono un frequentatore abituale di questo newsgroup (mi trovate
invece spesso su it.comp.sicurezza.crittografia e a volte su
it.arti.fumetti o it.arti.animazione) ma volevo rendervi partecipi della
mia felicità, dopo il mio primo "incontro" con le JNI.
Iniziamo dall'inizio... l'inizio è stata la mia (solita) indignazione
per la bassa risoluzione di System.currentTimeMillis(), ovvero 1 ms nel
migliore dei casi, ma spesso molto peggio (ad esempio Windows usualmente
usa 'step' da 15-16 ms).
Abituato, nel mio passato da "purista C/assembler" a utilizzare
l'istruzione RDTSC, disponibile dal Pentium in su, per poter ottenere il
numeri di cicli di clock trascorsi dall'ultimo reboot, mi sono chiesto
se fosse possibile ottenere tale numero anche in Java.
Il mio primo pensiero, ovviamente, sono state le JNI: potendo scrivere
un metodo in C avrei potuto utilizzare la cara vecchia RDTSC pur
mantenendo nel resto del programma la "comodità" del Java a cui mi sono
oramai abituato.
La mia sorpresa è stata, più che altro, la facilità di questo processo,
che supponevo molto più complicato! (a saperlo l'avrei provato prima)
Ho iniziato per tentativi, un po' a caso, ed avevo fatto quasi tutto nel
modo corretto, ma non avevo detto al compilatore di emettere la DLL con
la convenzione di chiamat Pascal; consilgio che ho trovato in questa
pagina (in inglese):
<http://www.inonit.com/cygwin/jni/helloWorld/>
Riassumo in breve (e in itailano) i passi che ho seguito:
1. creare la classe Java che ospiterà il metodo nativo
public class RDTSC {
~ public static native long getClock();
}
2. richiamare "javah" per creare l'header C adatto alle JNI, genererà
qualcosa di simile a:
JNIEXPORT jlong JNICALL Java_RDTSC_getClock (JNIEnv *, jclass);
3. scrivere il metodo C corrispondente all'header auto-generato
#include "RDTSC.h"
JNIEXPORT jlong JNICALL Java_RDTSC_getClock(JNIEnv * env, jclass
thisClass) {
~ asm ( "rdtsc" );
}
4. compilare il file C (in questo esempio utilizzo "gcc" per Win32,
parte del progetto CygWin, ho utilizzato il parametro -mno-cygwni per
creare una DLL indipendende dalla DLL CygWin, ma basata direttamente
sulle librerie interne di Windows)
gcc -mno-cygwin -I/cygdrive/c/Java2/include/
- -I/cygdrive/c/Java2/include/win32/ -Wl,--add-stdcall-alias -shared -o
RDTSC.dll RDTSC.c
da notare:
- - aggiungere sia il path Java2/include che Java2/include/<piattaforma>,
entrambi sono richiesti per avere le JNI
- - l'opzione -Wl,--add-stdcall-alias avverte il linker di esportare le
funzioni anche in formato Pascal (altrimenti non verranno trovate)
5. modificare la classe per fargli caricare la libreria share (non viene
vista in automatico, va caricata!):
public class RDTSC {
~ public static native long getClock();
~ static {
~ System.loadLibrary("RDTSC");
~ }
}
6. lanciare un programma che ne testi le funzionalità, specificando
eventualmente il path della libreria shared generata con
- -Djava.library.path=....
In seguito ovviamente ho "arricchito" la classe in modo da poter essere
più "comoda", ma quello che ho aggiunto sono solo piccole utilità, il
nocciolo della questione è sempre esattamente come lo ho decritto qua.
Dopo piccoli test posso dire che la 'precisione' (ovvero la differenza
riscontrata da due chiamate consecutive) del metodo RDTSC.getClock() è
di circa 50 cicli di clock (test fatti con JDK 1.4 su WinXP, processore
AthlonXP 1900+), nonostante la garbage collection possa creare gradini
di anche 6 milioni di cicli di clock (pochi millisecondi).
Se siete interessati alla mia implementazione potete trovarla sul mio
CVS, fa parte della mia libreria (in fase di costruzione) LapInt.
I file che vi interessano sono RDTSC.java, RDTSC.c e anche il relativo
Makefile che unisce il tutto.
L'indirizzo della cartella che contiene i files è il seguente:
<http://home.lapo.it/cgi-bin/viewcvs.cgi/lapint/it/lapo/util/>
in caso di problemi di DNS con http://home.lapo.it/ (ultimamente ne ha),
potete usare il nome alternativo http://lapo.m4d.sm/
La libreria LapInt è coperta da licenza GPL v2.
Lapo
- --
L a p o L u c h i n i
l a p o @ l a p o . i t
w w w . l a p o . i t /
http://www.megatokyo.it
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAj/uUIIACgkQaJiCLMjyUvtACwCg3piVCmZl+b7lh1w+/b1mekKz
gesAn1LjqsSspxPJV2GsMaLOvpM0t+x6
=tGy3
-----END PGP SIGNATURE-----
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|