Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

230
Vistas
Despliegue de bucle en funciones en línea en C

Tengo una pregunta sobre la optimización del compilador de C y cuándo/cómo se desarrollan los bucles en las funciones en línea.

Estoy desarrollando un código numérico que hace algo como el siguiente ejemplo. Básicamente, my_for() calcularía algún tipo de plantilla y llamaría a op() para hacer algo con los datos en my_type *arg para cada i . Aquí, my_func() envuelve my_for() , creando el argumento y enviando el puntero de función a my_op() ... cuyo trabajo es modificar el i -ésimo doble para cada uno de los arreglos dobles ( arg->n ) arg->dest[j] .

 typedef struct my_type { int const n; double *dest[16]; double const *src[16]; } my_type; static inline void my_for( void (*op)(my_type *,int), my_type *arg, int N ) { int i; for( i=0; i<N; ++i ) op( arg, i ); } static inline void my_op( my_type *arg, int i ) { int j; int const n = arg->n; for( j=0; j<n; ++j ) arg->dest[j][i] += arg->src[j][i]; } void my_func( double *dest0, double *dest1, double const *src0, double const *src1, int N ) { my_type Arg = { .n = 2, .dest = { dest0, dest1 }, .src = { src0, src1 } }; my_for( &my_op, &Arg, N ); }

Esto funciona bien. Las funciones están en línea como deberían y el código es (casi) tan eficiente como haber escrito todo en línea en una sola función y desenrollar el bucle j , sin ningún tipo de my_type Arg .

Aquí está la confusión: si configuro int const n = 2; en lugar de int const n = arg->n; en my_op() , entonces el código se vuelve tan rápido como la versión de función única desenrollada. Entonces, la pregunta es: ¿por qué? Si todo se integra en my_func() , ¿por qué el compilador no ve que estoy definiendo literalmente Arg.n = 2 ? Además, no hay ninguna mejora cuando realizo explícitamente el límite en el j loop arg->n , que debería verse como el int const n = 2; después de incrustar. También intenté usar my_type const en todas partes para señalar realmente esta constante al compilador, pero simplemente no quiere desenrollar el bucle.

En mi código numérico, esto equivale a alrededor de un 15% de impacto en el rendimiento. Si importa, ahí, n=4 y estos bucles j aparecen en un par de ramas condicionales en un op() .

Estoy compilando con icc (ICC) 12.1.5 20120612. Probé #pragma unroll . Aquí están mis opciones de compilador (¿me perdí alguna buena?):

-O3 -ipo -static -unroll-aggressive -fp-model precise -fp-model source -openmp -std=gnu99 -Wall -Wextra -Wno-unused -Winline -pedantic

¡Gracias!

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Bueno, obviamente el compilador no es lo suficientemente 'inteligente' para propagar la constante n y desenrollar el ciclo for . En realidad, es seguro ya que arg->n puede cambiar entre instanciación y uso.

Para tener un rendimiento constante en todas las generaciones de compiladores y exprimir al máximo su código, realice el desenrollado a mano.

Lo que la gente como yo hace en estas situaciones (el rendimiento es el rey) es confiar en las macros.

Las macros se 'en línea' en las compilaciones de depuración (útil) y se pueden crear plantillas (hasta cierto punto) utilizando parámetros de macro. Se garantiza que los parámetros de macro que son constantes de tiempo de compilación permanecerán así.

over 4 years ago · Santiago Trujillo Denunciar

0

Es más rápido, porque su programa no asigna memoria a la variable.

Si no tiene que realizar ninguna operación en valores desconocidos, se tratan como si fueran #define constant 2 con verificación de tipo. Simplemente se agregan durante la compilación.

¿Podría elegir una de las dos etiquetas (me refiero a C o C ++), es confuso, porque los idiomas tratan los valores const de manera diferente: C los trata como variables normales cuyo valor simplemente no se puede cambiar, y en C ++ lo hacen o no No tiene memoria asignada según el contexto (si necesita su dirección o si necesita calcularlos cuando el programa se está ejecutando, entonces se asigna memoria).

Fuente: "Pensando en C++". Sin cita exacta.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda