PDA

Ver la Versión Completa : ¿Cómo puede esta optimización ser mas lenta? (código en C)


bicho_visacoso
11/12/11, 22:54:21
Hola,

Para mi aplicación estoy escribiendo código en C usando el NDK y me he encontrado con algo que me ha llamado la atención.

Tengo el siguiente código que aplica un aumento de exposición a la foto:

for(c = 0; c<tamaño_foto; c++){
pixel_rojo[c]=pixel_rojo[c]*exposicion; //exposición es un double que se recibe como parámetro
pixel_verde[c]=pixel_verde[c]*exposicion;
pixel_azul[c]=pixel_azul[c]*exposicion;
}

El tamaño de la foto es un buffer de 1280x800, osea 3 millones de multiplicaciones entre int y double. Tarda unos 0,160 segundos en realizarse en mi tablet.

Intenté reducir el número de multiplicaciones con lo siguiente:

int matriz_exposicion[65536]; //2^16 valores posibles de cada pixel
for(c=0;c<65536;c++){
matriz_exposicion[c]=c*exposicion;
}

for(c=0;c<tamaño_foto;c++){
pixel_rojo[c]=matriz_exposicion[pixel_rojo[c]];
pixel_verde[c]=matriz_exposicion[pixel_verde[c]];
pixel_azul[c]=matriz_exposicion[pixel_verde[c]];
}

Con este código se realizan solo 65536 multiplicaciones entre int y double y 3 millones de copias de datos desde matriz_exposicion a las matrices de pixel.

Pues este segundo código resulta que tarda 0,2 segundos en ejecutarse, un 25% más lento.

¿Puede ser que los procesadores ARM sean tan lentos copiando información o estoy haciendo algo mal? :oh:

Un saludo.
David.

FordPrefect
12/12/11, 10:18:18
Hola,

La verdad es que suena raro.

No se si has escrito el código de memoria o lo has copiado y pegado pero tal como está, estás copiado el verde sobre el azul.

pixel_verde[c]=matriz_exposicion[pixel_verde[c]]; pixel_azul[c]=matriz_exposicion[pixel_verde[c]];

Lo peor es que esta corrección hara que sea incluso más lento :-(

La verdad es que no se me ocurre gran cosa:

- ¿Seguro que pixel_verde[] está declarado como int?
- ¿Has probado en otras tabletas?

bicho_visacoso
13/12/11, 13:01:19
Hola, lo escribí de memoria, habría que modificar eso pero poco cambia la cosa...

Las matrices pixels son todas int, pero por si influye en algo son globales, la de exposición es local. ¿puede ser que tenga que declararla de otra forma o compilar con algún parámetro extra?.

Compilo desde la línea de comandos ejecutando ndk-build, no desde el eclipse...

Muchas gracias y un saludo.
David

LeiNaD_87
19/12/11, 16:45:26
Me pierdo un poco como está la arquitectura de los moviles... pero, ¿estas teniendo en cuenta que en el segundo caso estás reservando memoria para 65k enteros?

Otra posible razón, es la localidad de los datos... en el primer caso les pixel_rojo y escribes en pixel_rojo ( sigue en caché ). En el segundo caso lees de un sitio y escribes en otro...

Este código aumenta aúm mas la localidad, pero dudo que sea más rápido:
for(c = 0; c<tamaño_foto; c++)
pixel_rojo[c]=pixel_rojo[c]*exposicion;
for(c = 0; c<tamaño_foto; c++)
pixel_verde[c]=pixel_verde[c]*exposicion;
for(c = 0; c<tamaño_foto; c++)
pixel_azul[c]=pixel_azul[c]*exposicion;


Salu2!!