Estuve jugando un poco con assembler para ver la diferencia con C (usando GCC como compilador).
La operación realizada fue aplicar una máscara a una imagen en blanco y negro, es decir por un lado tengo el puntero de la imagen original y por el otro un puntero de una imagen que contiene todos los bytes en 0xFF menos aquellos bytes que deseo llevar a 0x00 (negro), para luego aplicar una AND entre las dos imágenes.
Se usa OpenCv para obtener la imagen original a partir de un archivo y al finalizar la rutina, se guarda el resultado en otro archivo.
Código en C:
	
	
	
		PHP:
	
	
		void enmascarar(void *ptr,void *image_data,unsigned int tamanio)
{
	unsigned int cont_tamanio;
	for(cont_tamanio=0;cont_tamanio<tamanio;cont_tamanio++)
    {
		*(unsigned char*)(image_data+cont_tamanio)&=*(unsigned char*)(ptr+cont_tamanio);
    }
}
	 
 
Código en Assembler común:
	
	
	
		PHP:
	
	
		.global enmascarar
.type enmascarar, %function
enmascarar:
   push {r4-r10}
   
   mov r4, #0
 
   LOOP:      
    ldrb r5, [r0, r4]
    ldrb r6, [r1, r4]
    
    AND r5, r5, r6
    
    strb r5, [r1, r4]    
   
   add r4, r4, #1
   cmp r2, r4
   BNE	LOOP
   
   pop {r4-r10}
   mov pc, lr
	 
 
En Assembler, r0-r3 son los registros usados como argumentos de la función (en este caso r3 no se usa), r4-r11 se pueden usar como registros de uso general, pero deberán guardarse antes de usar y al final de la rutina devolver sus valores. En este caso la función no devuelve nada, pero en caso de hacerlo, se hace mediante el registro r0-r1.
El código se puede mejorar un poco ahorrando la instrucción "ADD" y "CMP" usando directamente una resta ("SUB") y en vez de usar r4 como índice, se podrían usar los punteros originales de esta forma:
	
	
Carga en r5 el contenido apuntado por r0 y suma en 1 a r0. Será necesario usar otro registro como puntero de destino:
	
	
	
		PHP:
	
	
		...
mov r7, r1
LOOP:
...
  strb r5, [r7]!
	 
 
Código en Assembler usando instrucciones NEON:
	
	
	
		PHP:
	
	
		.global enmascarar
.type enmascarar, %function
enmascarar: @r0: ptr de la máscara, r1: ptr de la imagen (destino), r2: cantidad de píxeles
   push {r4-r10}
   mov r2, r2, LSR#4 @Al trabajar con variables de 128bits (qn), trabajo de a 16bytes => la cantidad de píxeles deberán ser divididos por 16 o desplazar 4 veces a la derecha los bits 
   mov r5, r1
   mov r4, #0
   
   LOOP:      
     vld1.8 {q0}, [r0]! @Cargo los 1eros 16 bytes de la máscara y le sumo 16 a r0 (!= suma el índice por la cantidad de bytes leídos)
     vld1.8 {q1}, [r1]! @Similar al anterior
    
     vand q2, q0, q1
     
     vst1.8 {q2}, [r5]! @Almaceno en la memoria apuntada por r5 el resultado de la operación.       
   
   add r4, r4, #1
   cmp r2, r4
   BNE	LOOP
   
   pop {r4-r10}
   mov pc, lr
	 
 
Al igual que antes, el loop se podría resolver con el uso de "SUB" en vez de "ADD" y "CMP".
Llamada reiterativa en todos los casos:
	
	
	
		PHP:
	
	
		unsigned int current_timestamp() {
    struct timeval te;
    gettimeofday(&te, NULL); // get current time
    return te.tv_usec; 
}
main()
{
 ...
  for(cont=0; cont<10; cont++)
    {
        t_0=current_timestamp();
        enmascarar(ptr, img->imageData, img->width*img->height);
        t_1=current_timestamp();
        printf("La diferencia de tiempo (uS): %d\n",(t_1-t_0));
    }
 ...
}
	 
 
Resultados:
- Con C:
	
		
			
				consola dijo:
			
		
	
	
		
		
			La diferencia de tiempo (uS): 8691
La diferencia de tiempo (uS): 8669
La diferencia de tiempo (uS): 8647
La diferencia de tiempo (uS): 8661
La diferencia de tiempo (uS): 8652
La diferencia de tiempo (uS): 8700
La diferencia de tiempo (uS): 8995
La diferencia de tiempo (uS): 8687
La diferencia de tiempo (uS): 8683
La diferencia de tiempo (uS): 8678
		
		
	 
- Con Assembler común:
	
		
			
				consola dijo:
			
		
	
	
		
		
			La diferencia de tiempo (uS): 3483
La diferencia de tiempo (uS): 3445
La diferencia de tiempo (uS): 3309
La diferencia de tiempo (uS): 3385
La diferencia de tiempo (uS): 3448
La diferencia de tiempo (uS): 3422
La diferencia de tiempo (uS): 3429
La diferencia de tiempo (uS): 3431
La diferencia de tiempo (uS): 3386
La diferencia de tiempo (uS): 3424
		
		
	 
- Con Assembler usando instrucciones Neon:
	
		
			
				consola dijo:
			
		
	
	
		
		
			La diferencia de tiempo (uS): 1091
La diferencia de tiempo (uS): 1123
La diferencia de tiempo (uS): 1120
La diferencia de tiempo (uS): 1128
La diferencia de tiempo (uS): 1110
La diferencia de tiempo (uS): 1125
La diferencia de tiempo (uS): 1121
La diferencia de tiempo (uS): 1122
La diferencia de tiempo (uS): 1197
La diferencia de tiempo (uS): 1124
		
		
	 
Hay una diferencia considerable a pesar de que la operación es simplemente una "AND", incluso el tiempo obtenido por la función "current_timestamp" tal vez no sea la mejor referencia de tiempo, pero dá una buena idea de la optimización del uso de Assembler en ciertas rutinas críticas.
Les dejo la imagen original y su resultado.
NOTA: originalmente en el programa guardo el archivo en BMP, por el tamaño, el foro no me dejo subir dicho archivo, por lo tanto lo convertí a jpg. Podía haber obtenido el jpg directamente desde el OpenCv, pero bue... no lo hice, tampoco cambia el resultado obtenido.