Possiedo un programma Java progettato per visualizzare le immagini in un formato di file personalizzato, leggere una libreria C++ utilizzando JNI. I dati vengono caricati in un array di caratteri sul lato C++ e trasferiti in una BufferedImage sul lato Java. Poiché sezioni dell'immagine possono essere rimosse dalla memoria e devono essere ricaricate abbastanza regolarmente, quindi voglio che queste operazioni siano il più veloci possibile.Trasferimento efficiente di grandi quantità di dati di byte da C++ a Java
Il modo in cui sto facendo questo è che i dati vengono letti dal file in un buffer nella memoria della libreria C++. Per popolare la BufferedImage, il codice Java effettua una chiamata alla funzione JNI per ogni pixel da leggere da questo buffer e, se necessario, carica un altro blocco di dati nel buffer. Funziona, ma con un overhead superiore a quello che vorrei.
Quello che ho intenzione di fare per migliorare questo è passare l'oggetto BufferedImage al codice C++ usando una chiamata JNI, ed effettuare chiamate di funzione su di esso da quel lato. Ho fatto ricerche su JNI il più possibile, ma non sono stato in grado di scoprire se ci sono costi nella modifica di oggetti Java da una libreria C++ caricata dalla JVM. Questo è un buon modo per implementare questo, o c'è un modo più veloce per trasferire grandi quantità di dati di byte con JNI?
Una chiamata per pixel suona male! Sarebbero miliardi di chiamate per le immagini più grandi. Che dire dell'acquisizione di blocchi o righe raster (ad esempio unità di immagini più grandi) contemporaneamente? Le righe raster possono essere lette sequenzialmente come impacchettate ed evitare ulteriori conversioni? – user2246674
Sì, le righe e i blocchi possono essere letti in un buffer sul lato C++. Ho fatto un po 'di ottimizzazione sul lato C++. Il problema è che non conosco un modo efficiente per trasferire i dati su java, quindi eseguo una chiamata separata su ciascun pixel per leggere i dati dal buffer C++. – resueman
@resuerman Può qualcosa [WritableRaster.setSamples] (http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/image/WritableRaster.html#setSamples (int,% 20int,% 20int ,% 20int,% 20int,% 20double [])) da utilizzare? Se è possibile, potrebbe essere solo trovare un modo per (più efficientemente) caricare i dati in un array Java. C'è un modo per bloccare una memoria array e/o wrap [C++] ed evitare una copia [primaria]? Anche con un'operazione di copia aggiuntiva (C++ -> Array Java-> Raster), dovrebbe comunque ridurre notevolmente il numero di chiamate JNI. Inoltre (e immagino che questo suoni "extra-intelligente"), possono essere usate le OpenGL (texture) qui? – user2246674