Android de varios núcleos

He ejecutado algoritmo paralelo simple dibujo el conjunto mandelbrot para probar los cálculos paralelos en un Nexus 7 (Tegra 3, 4 + 1 núcleos). Después de funcionar varias veces consigo 1.5 segundos para el serial y 1.0 para el paralelo, pero el paralelo y el serial vienen realmente cerca de uno a en 1.3 segundos.

El cuadrado es 700×700 pixeles, y el código del mandelbrot que utilizo es de

Http://rosettacode.org/wiki/Mandelbrot_set#Java

La implementación paralela se ejecuta dos mitades de mandelbrot como este

public void mandelbrotParallel() { Thread t1 = new Thread(new Runnable() { public void run() { mandelbrotOne(); } }); Thread t2 = new Thread(new Runnable() { public void run() { mandelbrotTwo(); } }); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mHandler.post(new Runnable() { public void run() { v.setBmp(bmp); v.invalidate(); } }); } 

He corrido una simple adición vectorial antes y he encontrado resultados anecdóticos similares (sin rigor científico). Así que me pregunto si hay algo especial que uno tiene que hacer para conseguir Android para encender múltiples núcleos para obtener una tarea.

Basado en conversaciones rápidas con Google, podría ser que los núcleos estén latentes y esperar a que el cálculo sea verdaderamente largo (varios segundos) antes de que los núcleos estén encendidos … ¿Es esto cierto? Si es así, ¿hay llamadas API desde Java (no JNI) que se pueden hacer para activar de forma preventiva los núcleos?

Esto suena como un candidato para RenderScript . En pocas palabras, le permite realizar operaciones computacionalmente caras que aprovechan todos los recursos de aceleración disponibles (núcleos múltiples, cálculo de GPU, dsp, etc.). De los documentos:

Renderscript le da a sus aplicaciones la capacidad de ejecutar operaciones con paralelización automática en todos los núcleos de procesador disponibles. También soporta diferentes tipos de procesadores como la CPU, GPU o DSP. Renderscript es útil para aplicaciones que realizan procesamiento de imágenes, modelado matemático o cualquier operación que requiera mucho cálculo matemático.

Tendrías que reescribir tu código de Mandelbrot en C, pero no tendrás que dividirlo en pedazos ya que la paralelización será atendida por ti.

El uso de RenderScript desde el código de Android es sencillo como se describe aquí .

Un sistema Android normal intenta ser conservador. Por lo tanto, si crea un nuevo hilo e inicia algunos cálculos pesados, el kernel de Linux se ejecutará primero en un núcleo y aumentará su velocidad de núcleo. Una vez que el núcleo ha estado "ocupado" sobre un cierto umbral durante un tiempo, sólo entonces el núcleo comienza otro núcleo.

Lo mismo es cierto en la otra dirección: una vez que el sistema se calma, se apagará lentamente núcleos y reducir la frecuencia.

Desde el punto de vista del desarrollador, no puedes influir en esto en un Android "normal". Android no tiene API para despertar una cierta cantidad de núcleos o establecer una determinada frecuencia central.


Si puedes cambiar a un Android arraigado , tienes más opciones, ya que el kernel regular de Linux tiene opciones para influenciar las frecuencias centrales y el número de núcleos activos. Esto se hace a través de "gobernadores". Un kernel normal de Linux tiene bastantes opciones. Para esta pregunta, usted está interesado en establecer el gobernador de rendimiento , que mantendrá un núcleo despierto y en su máxima frecuencia.

La interfaz del kernel de Linux está en el sistema de archivos / sys . Voy a mostrar los comandos de la shell adb aquí y dejarlo a usted para convertirlo en Java abrir, leer y escribir comandos.

 cd /sys/devices/system/cpu 

Dentro de este directorio, encontrará archivos virtuales que indican cuántos núcleos están presentes en el sistema:

 cat possible 

Debe dar la respuesta 0-3 en su caso de Tegra 3. El núcleo no sabe que si sólo un núcleo está funcionando, se mueve secretamente hacia el núcleo de bajo consumo de repuesto. También hay directorios cpu0 cpu1 cpu2 cpu3 . Dependiendo de la versión del kernel, sólo pueden aparecer si se activa un núcleo. Cada uno de los directorios de cpu contiene un directorio cpufreq donde se puede interactuar con el subsistema cpufreq . Debe contener un archivo scaling_available_governors que muestre qué gobernadores de cpu están disponibles. Sólo en un sistema enraizado, usted puede hacer:

 echo "performance" >cpu0/cpufreq/scaling_governor 

Para configurar el regulador que mantendrá el núcleo funcionando en su frecuencia más alta. En un sistema no enraizado, obtendrá el error "permiso denegado".


Para mostrar la influencia de este comportamiento, Vector Fabrics creó una aplicación de prueba que realiza un algoritmo de penetración en OpenCV en paralelo. La aplicación mide el rendimiento secuencial y paralelo hasta 4 núcleos. Incluso cuando se ejecuta la versión paralela dos veces, las mediciones varían debido a la puesta en marcha de los núcleos. Echa un vistazo a ti mismo (descarga de la tienda de aplicaciones): http://www.vectorfabrics.com/products/case-study/opencv_inpaint

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.