Escribí algunos códigos Java para aprender más sobre el marco Ejecutor.¿Por qué este código no muestra ninguna ganancia de rendimiento significativa cuando uso múltiples hilos en una máquina de cuatro núcleos?
Específicamente, escribí código para verificar la Collatz Hypothesis - esto dice que si iterativa aplicar la siguiente función para cualquier número entero, se llega a 1 con el tiempo:
f (n) = ((n% 2) = = 0)? n/2: 3 * n + 1
CH aún no se ha probado, y pensé que sería una buena forma de aprender sobre el ejecutor. Cada hilo tiene asignado un rango [l, u] de enteros para verificar.
Específicamente, mi programa tiene 3 argumentos: N (el número al que quiero verificar CH), RANGESIZE (la longitud del intervalo que un subproceso debe procesar) y NTHREAD, el tamaño del subproceso de subprocesos.
Mi código funciona bien, pero vi una aceleración mucho menor que la esperada, del orden del 30% cuando pasé de 1 a 4 hilos.
Mi lógica era que el cálculo está completamente vinculado a la CPU, y cada subtarea (verificando CH para un rango de tamaño fijo) toma más o menos el mismo tiempo.
¿Alguien tiene ideas de por qué no veo un incremento de 3 a 4 veces en la velocidad?
Si puede informar sus tiempos de ejecución a medida que aumenta el número de subprocesos (junto con la máquina, JVM y SO) que también sería genial.
Específicos
Runtimes:
java -d64 -server -cp. Collatz 10000000 1000000 4 => 4 hilos, lleva 28412 milisegundos
java -d64 -server -cp. Collatz 10000000 1000000 1 => 1 hilo, toma 38286 milisegundos
Procesador:
Q6600 Quadcore Intel a 2,4 GHz, 4 GB. La máquina está descargada.
Java:
java version "1.6.0_15" Java (TM) SE Runtime Environment (build 1.6.0_15-b03) Java HotSpot (TM) de 64 bits del servidor VM (build 14.1-b02, de modo mixto)
OS:
Linux quad0 2.6.26-2-amd64 # 1 SMP Martes 9 de marzo 22:29:32 UTC 2010 x86_64 GNU/Linux
Código: (No puedo obtener el código para publicar, creo que es demasiado largo para los requisitos de SO, la fuente está disponible en Google Docs
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyRunnable implements Runnable {
public int lower;
public int upper;
MyRunnable(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
@Override
public void run() {
for (int i = lower ; i <= upper; i++) {
Collatz.check(i);
}
System.out.println("(" + lower + "," + upper + ")");
}
}
public class Collatz {
public static boolean check(BigInteger X) {
if (X.equals(BigInteger.ONE)) {
return true;
} else if (X.getLowestSetBit() == 1) {
// odd
BigInteger Y = (new BigInteger("3")).multiply(X).add(BigInteger.ONE);
return check(Y);
} else {
BigInteger Z = X.shiftRight(1); // fast divide by 2
return check(Z);
}
}
public static boolean check(int x) {
BigInteger X = new BigInteger(new Integer(x).toString());
return check(X);
}
static int N = 10000000;
static int RANGESIZE = 1000000;
static int NTHREADS = 4;
static void parseArgs(String [] args) {
if (args.length >= 1) {
N = Integer.parseInt(args[0]);
}
if (args.length >= 2) {
RANGESIZE = Integer.parseInt(args[1]);
}
if (args.length >= 3) {
NTHREADS = Integer.parseInt(args[2]);
}
}
public static void maintest(String [] args) {
System.out.println("check(1): " + check(1));
System.out.println("check(3): " + check(3));
System.out.println("check(8): " + check(8));
parseArgs(args);
}
public static void main(String [] args) {
long lDateTime = new Date().getTime();
parseArgs(args);
List<Thread> threads = new ArrayList<Thread>();
ExecutorService executor = Executors.newFixedThreadPool(NTHREADS);
for(int i = 0 ; i < (N/RANGESIZE); i++) {
Runnable worker = new MyRunnable(i*RANGESIZE+1, (i+1)*RANGESIZE);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
long fDateTime = new Date().getTime();
System.out.println("time in milliseconds for checking to " + N + " is " +
(fDateTime - lDateTime) +
" (" + N/(fDateTime - lDateTime) + " per ms)");
}
}
Su código de enlace falló para mí. –
Creo que necesita cambiar la configuración en su documento de Google. Obtengo "Google Docs: página no disponible". –
Pude obtener el código. Lo agregué al final de la pregunta. –