¿Cómo se puede calcular un raster de forma eficiente (en Python), dado un conjunto formado por miles de millones de cuadros delimitadores (leídos secuencialmente de un archivo), y dado que los valores del raster para cada celda deben dar el número de cuadros delimitadores superpuestos?
Para una trama de 4000 * 4000
He cronometrado la creación de la matriz numpy:
$ python -m timeit 'import numpy' 'a = numpy.zeros(shape=(4000,4000))'
10 loops, best of 3: 51.7 msec per loop
Creación de matrices estándar en python:
$ python -m timeit 'a = 4000*[0]' 'for i in range(4000):' ' a[i]=4000*[0]'
10 loops, best of 3: 218 msec per loop
Así que numpy es más rápido, pero todavía 50 mseg por bucle, con mil millones de iteraciones, produce un tiempo de ejecución igual a un año (0,05mseg * 1000000000 / 60 / 60 / 24 / 365 = 1,5 años)
Así que no es una opción muestrear cada polígono. ¿Cuál es el enfoque típico para este problema?
0 votos
Quiero resolverlo en un solo ordenador, así que nada de soluciones map/reduce, por favor :-)
2 votos
No entiendo la importancia de cronometrar las operaciones de creación de tramas. Este proceso necesita crear el raster subyacente exactamente una vez. Dominar el tiempo de ejecución será la cuestión de incrementar los recuentos en los interiores de las cajas delimitadoras. Todo lo que hay que hacer es optimizar este bucle interior. Se puede hacer que vaya extremadamente rápido en un lenguaje compilado como C o Fortran.
0 votos
La creación de un rastro cero es mi aproximación cruda sobre el tiempo que se tardaría en incrementar los recuentos en un caso malo. Es un límite inferior de lo que se tarda en el peor de los casos, en el que el polígono es tan grande como la trama, con lenguaje compilado o no. La verdadera pregunta es, dado un raster de 4000x4000, ¿qué tan rápido puede incrementarse todo el raster en C o Fortran en una laptop de nivel medio, back-of-the-envelope?
0 votos
@whuber: ¿Cómo optimizarías el bucle interno, sin tener en cuenta el idioma?
2 votos
Un BB determina un rango de filas indexadas por i0..i1 y un rango de columnas j0..j1. En el almacenamiento fila por fila, se puede incrementar X(i,j0..j1) muy rápidamente (es un almacenamiento contiguo). Probablemente se puede hacer a unos 3E9 incrementos/seg. e incluso vectorizarlo si se quiere para una operación mucho más rápida. Bucle i de i0 a i1: eso se encarga de un solo BB. Para cada BB tienes que convertir sus coordenadas de frontera en (i0,i1,j0,j1), pero eso no es mucha sobrecarga: se puede hacer más rápido de lo que puedes leer las coordenadas.
0 votos
En lo que respecta a la trama completa, se calcula que un solo núcleo tarda aproximadamente 1 milisegundo en incrementar toda la trama. Racimos enteros de filas estarán en la caché L3 simultáneamente para una actualización realmente rápida. Esta operación es altamente paralelizable: imagina lo que podrías hacer con, digamos, 1024 GPUs NVidia funcionando en paralelo...
1 votos
Hay este interesante blog en el sitio de ESRI que habla sobre el uso de python y el procesamiento multinúcleo, ¿puede ser de ayuda? blogs.esri.com/esri/arcgis/2011/08/29/multiproceso