Rendimiento del bucle de código C [continuación]

83

Esta pregunta continúa sobre mi pregunta aquí (con el consejo de Mystical):

Rendimiento del bucle de código C


Continuando con mi pregunta, cuando uso instrucciones empaquetadas en lugar de instrucciones escalares, el código que usa intrínsecos se vería muy similar:

for(int i=0; i<size; i+=16) {
    y1 = _mm_load_ps(output[i]);
    …
    y4 = _mm_load_ps(output[i+12]);

    for(k=0; k<ksize; k++){
        for(l=0; l<ksize; l++){
            w  = _mm_set_ps1(weight[i+k+l]);

            x1 = _mm_load_ps(input[i+k+l]);
            y1 = _mm_add_ps(y1,_mm_mul_ps(w,x1));
            …
            x4 = _mm_load_ps(input[i+k+l+12]);
            y4 = _mm_add_ps(y4,_mm_mul_ps(w,x4));
        }
    }
    _mm_store_ps(&output[i],y1);
    …
    _mm_store_ps(&output[i+12],y4);
    }

El rendimiento medido de este kernel es de aproximadamente 5.6 operaciones FP por ciclo, aunque esperaría que sea exactamente 4 veces el rendimiento de la versión escalar, es decir, 4.1,6 = 6,4 operaciones FP por ciclo.

Teniendo en cuenta el movimiento del factor de peso (gracias por señalarlo), el programa se ve así:

calendario

Parece que el programa no cambia, aunque hay una instrucción adicional después de la movssoperación que mueve el valor de peso escalar al registro XMM y luego usa shufpspara copiar este valor escalar en todo el vector. Parece que el vector de peso está listo para usarse por el mulpsmomento, teniendo en cuenta la latencia de conmutación de la carga al dominio de punto flotante, por lo que esto no debería incurrir en ninguna latencia adicional.

Las instrucciones movaps(alineadas, empaquetadas) addpsy mulpsque se usan en este kernel (verificadas con código ensamblador) tienen la misma latencia y rendimiento que sus versiones escalares, por lo que tampoco deberían incurrir en una latencia adicional.

¿Alguien tiene una idea de dónde se gasta este ciclo adicional por 8 ciclos, asumiendo que el rendimiento máximo que puede obtener este kernel es 6.4 operaciones FP por ciclo y se está ejecutando a 5.6 operaciones FP por ciclo?


Por cierto, aquí está el aspecto del ensamblaje real:

…
Block x: 
  movapsx  (%rax,%rcx,4), %xmm0
  movapsx  0x10(%rax,%rcx,4), %xmm1
  movapsx  0x20(%rax,%rcx,4), %xmm2
  movapsx  0x30(%rax,%rcx,4), %xmm3
  movssl  (%rdx,%rcx,4), %xmm4
  inc %rcx
  shufps $0x0, %xmm4, %xmm4               {fill weight vector}
  cmp $0x32, %rcx 
  mulps %xmm4, %xmm0 
  mulps %xmm4, %xmm1
  mulps %xmm4, %xmm2 
  mulps %xmm3, %xmm4
  addps %xmm0, %xmm5 
  addps %xmm1, %xmm6 
  addps %xmm2, %xmm7 
  addps %xmm4, %xmm8 
  jl 0x401ad6 <Block x> 
…
Ricky
fuente
Así que supongo que la pregunta ahora es: "¿Por qué la shufpsinstrucción agrega 1 ciclo cada 1.6 iteraciones?" Eso es difícil ...
Mysticial
Esperaría que no tuviera gastos generales, ya que la salida de shufpsdebería estar directamente disponible para la multpsoperación, ya que ambos son dominios FP
Ricky
Fácil de averiguar. Asegúrese de que el vector de peso no contenga valores de valores desnormalizados. Pruebe el bucle sin la instrucción shuffle. No producirá ningún resultado útil, pero tal vez encuentre qué instrucción le cuesta ciclos adicionales (sospecho que la mezcla, por supuesto).
Gunther Piez
@Mystical: Veo 0,75 ciclos por iteración de bucle añadidos. (¿No fue mi comentario sobre el uso de 5 ciclos en lugar de 4 lo que lo lleva a su respuesta allí ... :-))
Gunther Piez
3
Por un lado, ahora está exigiendo 4 veces el ancho de banda de la caché. ¿Qué tamaño tienen los datos? ¿Encajan en la caché L1?
Mysticial

Respuestas:

3

Intente usar la creación de perfiles EMON en Vtune o alguna herramienta equivalente como oprof

Perfilado EMON (Monitoreo de eventos) => como una herramienta basada en el tiempo, pero puede decirle qué evento de rendimiento está causando el problema. Sin embargo, primero debe comenzar con un perfil basado en el tiempo, para ver si hay una instrucción en particular que sobresalga. (Y posiblemente los eventos relacionados que le dicen con qué frecuencia hubo un puesto de retiro en esa IP).

Para utilizar el perfil EMON, debe ejecutar una lista de eventos, que van desde "los sospechosos habituales" hasta ...

Aquí, comenzaría con errores de caché, alineación. No sé si el procesador que está utilizando tiene un contador para las limitaciones del puerto de RF, debería hacerlo, pero agregué la creación de perfiles EMON hace mucho tiempo, y no sé qué tan bien se mantienen al agregar eventos apropiados para la microarquitectura.

También es posible que se trate de una entrada, búsqueda de instrucciones, parada. ¿Cuántos bytes hay en estas instrucciones, de todos modos? También hay eventos EMON para eso.


Responder al comentario de que Nehalem VTune no puede ver eventos L3: no es cierto. Aquí hay cosas que estaba agregando para comentar, pero no encajaban:

En realidad, HAY contadores de rendimiento para el LL3 / L3 $ / llamado Uncore. Me sorprendería inmensamente si VTune no los admite. Ver http://software.intel.com/sites/products/collateral/hpc/vtune/performance_analysis_guide.pdfapunta a VTune y otras herramientas como PTU. De hecho, incluso sin eventos LL3, como dice David Levinthal: "el procesador Intel® Core ™ i7 tiene un" evento de latencia "que es muy similar al evento EAR de datos de la familia de procesadores Itanium®. Este evento muestra cargas, registrando el número de ciclos entre la ejecución de la instrucción y la entrega real de los datos. Si la latencia medida es mayor que la latencia mínima programada en MSR 0x3f6, bits 15: 0, entonces el contador se incrementa. El desbordamiento del contador arma el mecanismo PEBS y en el siguiente evento que satisface el umbral de latencia, la latencia medida, la dirección virtual o lineal y la fuente de datos se copian en 3 registros adicionales en el búfer PEBS. Debido a que la dirección virtual se captura en una ubicación conocida, el controlador de muestreo también podría ejecutar una traducción virtual a física y capturar la dirección física. La dirección física identifica la ubicación de la casa de NUMA y, en principio, permite un análisis de los detalles de las ocupaciones de la memoria caché ". También señala, en la página 35, eventos de VTune como L3 CACHE_HIT_UNCORE_HIT y L3 CACHE_MISS_REMOTE_DRAM. A veces es necesario buscar el valor numérico códigos y programarlos en la interfaz de nivel inferior de VTune, pero creo que en este caso es visible en la bonita interfaz de usuario.


OK, en http://software.intel.com/en-us/forums/showthread.php?t=77700&o=d&s=lr un programador de VTune en Rusia (creo) "explica" que no se puede probar en Uncore eventos.

Está equivocado: podría, por ejemplo, habilitar solo una CPU y muestrear de manera significativa. También creo que existe la posibilidad de marcar los datos faltantes de L3 a medida que regresan a la CPU. De hecho, en general, el L3 sabe a qué CPU está devolviendo datos, por lo que definitivamente puede muestrear. Es posible que no sepa qué hyperthread, pero nuevamente puede deshabilitarlo y pasar al modo de un solo hilo.

Pero parece que, como es bastante común, tendría que trabajar ALREDEDOR de VTune, no con él, para hacer esto.

Pruebe primero el perfil de latencia. Eso está completamente dentro de la CPU, y es poco probable que la gente de VTune lo haya estropeado demasiado.

Y, repito, lo más probable es que su problema esté en el núcleo, no en L3. Entonces VTune debería ser capaz de manejar eso.


Intente "Contabilidad cíclica" según Levinthal.

Krazy Glew
fuente
Gracias por tu reacción. Utilizo VTune para analizar mi aplicación, pero el problema con la arquitectura nehalem es que la caché L3 pertenece a la off-coreparte del núcleo, por lo que no hay contadores de eventos de rendimiento disponibles para esta parte. Por lo tanto, es difícil estimar las pérdidas de caché, etcétera.
Ricky
En realidad, HAY contadores de rendimiento para el LL3 / L3 $ / llamado Uncore. Me sorprendería inmensamente si VTune no los admite. Ver software.intel.com/sites/products/collateral/hpc/vtune/…
Krazy Glew
Escribí más de lo que cabría en el comentario, traté de moverlo a la respuesta y limpiar el comentario original, pero los comentarios solo se pueden editar durante 5 minutos. Versión corta: VTune le permite ver fallas de caché L3. Incluso sin la compatibilidad con Uncore, se utiliza el perfil de latencia y tiene compatibilidad con Uncore.
Krazy Glew
Y, en general, sospecho que su problema no son las fallas de caché L3. Es más probable que sea un evento de front-end.
Krazy Glew
@KrazyGlew: Tu conjetura es correcta, es un chico ruso de la Federación Rusa. Aquí está su perfil en LinkedIn - linkedin.com/in/vtsymbal