2013-08-13 14 views
11

BASSAUtilizzo di sun.misc.Unsafe, qual è il modo più veloce per eseguire la scansione di byte da un ByteBuffer diretto?

supponga che ho un ByteBuffer diretta:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 

e assumere sto passando il buffer a un AsynchronousSocketChannel leggere blocchi di dati questa presa fino a X byte alla volta (1024 nell'esempio qui).

Il tempo di trasferimento dalla presa allo diretto ByteBuffer è fantastico perché si verifica tutto nello spazio di memoria del sistema operativo nativo; Non ho passato attraverso la JVM "emato-encefalica" barriera ancora ...

DOMANDA

Supponendo il mio compito è quello di eseguire la scansione attraverso tutti i byte letti nel byte dal buffer diretta, ciò che è il più veloce modo per me per fare questo?

Originariamente ho chiesto "... utilizzando sun.misc.Unsafe" ma forse è l'assunto sbagliato.

possibili approcci

Attualmente vedo tre approcci e quello Sono molto curioso di sapere è # 3:

  1. (DEFAULT) Usa ByteBuffer bulk-get per tirare byte direttamente dallo spazio nativo OS in un costrutto di byte interno [1024].
  2. (UNSAFE) Utilizzare gli op di Unsafe getByte per estrarre i valori direttamente da ByteBuffer ignorando tutti i limiti di controllo dei get op standard di ByteBuffer. La risposta di Peter Lawrey here sembrava suggerire che quei metodi nativi grezzi in Unsafe possono persino essere ottimizzati dal compilatore JIT ("intrinsics") alle istruzioni di una singola macchina che portano a tempi di accesso ancora più fantastici. (=== === AGGIORNAMENTO interessante, sembra che il sottostante DirectByteBuffer classe fa esattamente questo con la get/put ops per chi è interessato.)
  3. (banane) in una sorta crimine-contro-umanità di modo, utilizzando Unsafe, posso copy the memory region del ByteBuffer diretto allo stesso indirizzo di memoria che il mio byte [1024] esiste all'interno della VM e iniziare ad accedere all'array usando gli indici standard int? (In questo modo l'ipotesi che l'operazione "CopyMemory" può potenzialmente fare qualcosa di fantasticamente ottimizzato a livello di sistema operativo.

si verifichi a me che assumendo il CopyMemory operazione fa esattamente quello che pubblicizza, anche in più -optimal OS space, che l'approccio # 2 sopra è probabilmente ancora il più ottimizzato dal momento che non sto creando duplicati del buffer prima di iniziare a elaborarlo

Questo IS è diverso dalla domanda "can I use Unsafe to iterate over a byte[] faster?" perché non sono nemmeno pianificando di trascinare i byte in un byte [] internamente se non è necessario

Grazie per il tempo; solo curioso se qualcuno (Peter?) è diventato pazzo con Unsafe per fare qualcosa del genere.

risposta

1

ByteBuffer i metodi sono estremamente veloci, poiché questi metodi sono intrinsechi, VM li ha mappati a istruzioni di livello molto basso. Confronta questi due approcci:

byte[] bytes = new byte[N]; 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bytes.length; i++) 
      sum += bytes[i]; 

    ByteBuffer bb = ByteBuffer.allocateDirect(N); 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bb.remaining(); i++) 
      sum += bb.get(i); 

sulla mia macchina, la differenza è 0,67ns vs 0,81ns (per ciclo).

Sono un po 'sorpreso dal fatto che ByteBuffer non sia veloce come byte []. Ma penso che NON dovresti assolutamente copiarlo su un byte [] quindi accedere.

+0

Non conoscevo la proprietà "intrinseca" dei metodi ByteBuffer; intendi i metodi "nativi" nella classe DirectBuffer in particolare? In tal caso, ciò farebbe esattamente ciò che il n. 2 farebbe nel mio post in alto, quindi questa è un'ottima notizia. –

+0

@RiyadKalla intrinsic! = Nativo. I metodi intrinseci sono "hardcoded" nella JVM. – assylias

+0

@assylias Capisco; Mi riferivo (erroneamente) a quelli che ritenevo fossero metodi "nativi" nella classe impl di DirectByteBuffer (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java /nio/DirectByteBuffer.java) ma ora che lo guardo, vedo che non ci sono metodi "nativi", semplicemente sfrutta Unsafe per fare queste operazioni. Mi dispiace, grazie per la cattura. –

Problemi correlati