Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

229
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda