Ho codice che consuma un numero elevato (milioni attualmente, alla fine miliardi) di array relativamente brevi (5-100 elementi) di numeri casuali e fa una matematica non molto faticosa con loro. I numeri casuali essendo, beh, random, idealmente mi piacerebbe generarli su più core, poiché la generazione casuale di numeri è> 50% del mio runtime in profiling. Tuttavia, ho difficoltà a distribuire un numero elevato di piccole attività in un modo non più lento rispetto all'approccio a thread singolo.Buffering ad alte prestazioni per un flusso di randelli
Il mio codice attualmente sembra qualcosa di simile:
for(int i=0;i<1000000;i++){
for(RealVector d:data){
while(!converged){
double[] shortVec = new double[5];
for(int i=0;i<5;i++) shortVec[i]=rng.nextGaussian();
double[] longerVec = new double[50];
for(int i=0;i<50;i++) longerVec[i]=rng.nextGaussian();
/*Do some relatively fast math*/
}
}
}
approcci che ho preso che hanno non lavorato sono:
- 1+ discussioni che popolano un ArrayBlockingQueue, e il mio ciclo principale di consumare e popolando l'array (il boxing/unboxing era killer qui)
- Generare i vettori con un Callable (che produce un futuro) mentre si fanno le parti non dipendenti del calcolo matematico (sembra che il sovraccarico della indiretta sia superiore a qualsiasi guadagno di parallelismo che ho ottenuto)
- Utilizzo di 2 ArrayBlockingQueue, ciascuno compilato da un thread, uno per il corto e uno per i lunghi array (ancora circa il doppio rispetto al diretto single-threaded Astuccio).
Non sono alla ricerca di "soluzioni" per il mio particolare problema tanto quanto gestire il caso generale di generazione di grandi flussi di primitive indipendenti piccole in parallelo e consumo da un singolo thread.
@Gray troppo vero. Avvicinarsi a rispondere alla domanda. –
Aggiunto un esempio di come utilizzare Exchanger per generare numeri casuali in batch in background. –
Una combinazione di uno scambiatore per la comunicazione e il chunking di flussi più lunghi di rands ha fatto molto per le prestazioni. Grazie. – Bryce