La regla más importante es que es toda la teoría hasta su perfil. No me detengo con los que insisten en que el perfilado es todo (sin una teoría, no eres mejor que un Cultista de carga poniéndose coco en los oídos y esperando que venga el avión), pero tu teoría siempre puede ser incorrecta o incompleta, por lo que perfilar es crucial.
En general, queremos que el escaneo interno sea horizontal (en términos de la matriz, en lugar de la imagen, aunque para la mayoría de los formatos es el mismo). La razón es que con una gran variedad como:
00 01 02 03 04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
Va a ser expuesto como:
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Usted quiere ser exploración a lo largo bloques contiguos que se pueden cargar en cachés de la CPU y luego utilizados por completo, en lugar de escanear de bloque a bloque y la necesidad de cambiar regularmente el contenido de la caché de la CPU.
Esto es aún más importante si intentas paralelizar el algoritmo. Desea que cada subproceso trate sus propios bloques contiguos de memoria en lo que respecta tanto a la entrada como a la salida, en lugar de no solo sufrir el modo de código de subprocesamiento único con poca frecuencia de acierto de memoria caché, sino también causando que los búferes de cada uno se ensucien y necesita actualizar. Esta puede ser la diferencia entre el paralelismo que lleva a un aumento de la velocidad y la paralelización realmente ralentizando las cosas.
Otra cosa es la diferencia entre una matriz bidimensional byte[,]
en lugar de una matriz de matrices byte[][]
, cuyo comentario en su pregunta "matriz [y] [x]" me hace preguntar si quizás esté utilizando. Con el primero para obtener arr [1,2] La lógica es:
- revisar los límites
- calcular la posición (simple aritmética rápido)
- recuperar el valor.
Con este último, la lógica es:
- revisar los límites
- obtener matriz a través del puntero.
- Verificar límites
- Recuperar valor.
También hay menos memoria caché-hit-frecuencia. Este último tiene beneficios cuando se necesitan estructuras "dentadas", pero ese no es el caso aquí. 2D es casi siempre más rápido que una matriz de matrices.
Cosas que no me ven como probable que ayude, pero ciertamente ellos tratarían en su situación:
Usted puede encontrar un impulso de hacer su < => lógica 2d 1d. Tener una matriz de una dimensión donde idx = y * ancho + x. No debería hacer una diferencia apreciable, pero vale la pena intentarlo.
Las optimizaciones intentan tanto llamar al .Length
como omitir la verificación innecesaria de los límites, por lo que puede encontrar el izado manual y el cambio a la aritmética del puntero no gana nada, pero en caso de que realmente necesite bajar el tiempo Sin duda vale la pena perfilar.
Finalmente. ¿Ha perfilado qué tan rápido es su código para escanear la matriz y no hacer nada? Podría ser que otra parte del código sea el verdadero cuello de botella, y estás arreglando lo incorrecto.
Debería haber mencionado que la matriz es en realidad un BitmapData para asignación de color de mapa de bits:/sry ... –
Entonces, ¿ya está fijando la memoria? – Oded
¿Has intentado codificar cada solución y medir cuánto tiempo lleva? Eso te daría la respuesta más precisa. Pero si tuviera que adivinar, diría que las opciones 3 y 4 son probablemente un poco más rápidas que las opciones 1 y 2. – aroth