2012-02-23 8 views
6

He encontrado un rendimiento bastante pobre ejecutando algún código computacional en Ubuntu en una nueva máquina de estación de trabajo sin cabeza que estoy usando para el cálculo científico. Noté una diferencia en la velocidad al ejecutar un código ligeramente complejo en Ubuntu en comparación con mi viejo portátil Mac que uso para el desarrollo. Sin embargo, me las he arreglado para destilar abajo a un increíblemente sencillo ejemplo que todavía exhibe menos de stelar mejoras con respecto a mi vieja máquina:Rendimiento decepcionante en Ubuntu para la carga de trabajo computacional

#include <stdio.h> 
#include <math.h> 

int main() { 
     double res = 0.0; 
     for(int i=1; i<200000000; i++) { 
       res += exp((double) 100.0/i); 
     } 
     printf("%lf", res); 
     return(0); 
} 

Ahora el Mac es una de casi 5 años de edad de 2,4 GHz Core 2 Duo MacBook Pro ejecutando OS X 10.5 que ejecuta este código en aproximadamente 6.8 segundos. Sin embargo, en un nuevo Dell Core i7 de 3.4GHz que ejecuta Ubuntu 11.10, ¡tarda aproximadamente 6.1 segundos! ¿Puede alguien aclararme qué está pasando aquí, porque es absurdo que una laptop de casi 5 años esté dentro del 10% de una nueva estación de trabajo de escritorio? ¡Es aún más absurdo porque puedo ver que el Core i7 turboalimenta a casi 4GHz con herramientas de monitoreo!

Mac compilado con:

gcc -o test test.c -std=gnu99 -arch x86_64 -O2 

Ubuntu compilado con:

gcc -o test test.c -std=gnu99 -m64 -O2 -lm 

Gracias,

Louis

+1

Sin el código de ensamblador dado esto es inútil. Los compiladores pueden generar un código diferente (debido a las diferentes implementaciones de la biblioteca). Sería mucho mejor tener un código de referencia de nivel de ensamblador para garantizar el tiempo de ejecución. – Nobody

+0

Entiendo lo que dices, pero no voy a poder codificar mi aplicación científica en ensamblador. No dudo de que el hardware en bruto sea más rápido: mi problema es que la nueva estación de trabajo tiene un bajo rendimiento con el código C compilado, como se muestra, y me gustaría obtener ayuda para entender cómo puede suceder. En otras palabras, ¿qué tengo que hacer para que la nueva estación de trabajo publique números de rendimiento más en línea con los 5 años de evolución tecnológica que han pasado entre Core 2 Duo y Core i7? – user1055918

+0

@ user1055918 El compilador produce el ensamblaje que estamos buscando; no le pedimos que escriba el ensamblado. OS X llegó tarde a las CPU de Intel: hacen muchas cosas de manera diferente (por ejemplo, pueden suponer que existen ciertos conjuntos de instrucciones). Además, las bibliotecas pueden ser diferentes o pueden comportarse (ligeramente) de manera diferente. – justin

Respuesta

3

es absurdo que un viejo ordenador portátil casi 5 años es de dentro del 10% de una nueva estación de trabajo de escritorio

Tenga en cuenta que usted está benchmarking una función específica (exp). Realmente no sabemos si las dos implementaciones de la función exp() que está evaluando son idénticas (no es inconcebible que una esté mejor optimizada que la otra).

Si tuviera que comparar una función diferente, los resultados podrían ser bastante diferentes (quizás más en línea con sus expectativas, o no).

Si exp() es realmente el cuello de botella de su aplicación real, una posibilidad es considerar el uso de una aproximación rápida. Aquí hay un documento que ofrece una de estas aproximaciones: A Fast, Compact Approximation of the Exponential Function.

+0

También es muy posible que una implementación de 'exp' esté completamente ** mal **, es decir da resultados inexactos para muchas entradas. Las malas bibliotecas de matemáticas son más comunes de lo que crees, especialmente con la tensión entre las personas que quieren resultados correctos para la informática científica y los videojugadores que quieren que sus juegos en 3D funcionen lo más rápido posible y no importa si la pantalla o la física son un poco a moderadamente equivocado. –

+0

@aix Gracias, sí, supongo que asumí que Apple estaba usando la biblioteca de matemáticas GNU estándar, ya que es una base de Unix en OS X, pero parece que no. Sin embargo, estoy bastante sorprendido de que una función tan madura como exp() tenga un rendimiento significativamente peor en Linux. Recibo respuestas numéricamente idénticas, así que no creo que la implementación de Mac esté sacrificando la precisión. – user1055918

+0

@ user1055918: OS/X debe admitir un rango muy limitado de CPU, mientras que Linux debe admitir un rango mucho más amplio. Una posibilidad es que en OS/X, 'libm.a' se compila para hacer uso de algunas características de hardware recientes que la versión de Linux no puede usar mientras permanece ampliamente portable. – NPE

0

Estás comparando manzanas y naranjas, para Mac permites optimizaciones específicas de la arquitectura que no utilizas para ubuntu. Use -O3 -march=native en ambos para tener una comparación justa.

+1

Fuera de interés, probé estas opciones en mi caja de Ubuntu, y no hicieron una diferencia perceptible en el rendimiento. – NPE

+1

Gracias Jens - Lo intenté y también probé --march = corei7, pero no hubo diferencia en la velocidad, así que creo que los problemas son de otra parte en esta instancia. – user1055918

0

Algunas cosas para probar:

  • Asegúrese de que su CPU está en RUN fijo en su máxima velocidad durante el experimento. Se puede alternar arriba y hacia abajo, lo que añade un montón de gastos generales
  • Pin el programa de prueba a un núcleo usando taskset, por lo que el planificador del sistema operativo no migra alrededor
+0

Gracias, no sabía sobre 'taskset' ... Acabo de aprender una nueva herramienta de Linux. Desafortunadamente, no muestra una diferencia en el tiempo. Utilicé cpufreq-set para cambiar el gobernador al rendimiento y realmente no hay un cambio estadísticamente notable. Buenas ideas para probar, gracias. – user1055918

1

Como otros, que' simplemente comparando una implementación de la biblioteca matemática de exp() con otra. Si necesita bibliotecas matemáticas de alta calidad en Linux, le sugiero que consulte las herramientas de compilación de Intel (que vienen con un excelente conjunto de bibliotecas); también están disponibles para OS X y Windows.

+0

Sí, me da la impresión de que hay una convergencia de opiniones aquí que depende de las bibliotecas del sistema. Esto es algo así como una sorpresa para mí, ya que ingenuamente pensé que algo así como calcular exp() se optimizaría en el olvido por defecto. Es solo un cuello de botella que pude precisar, pero estoy seguro de que mi código real tendrá otros. ¿Hay bibliotecas de matemáticas gratuitas (a-la ATLAS en el espacio BLAS) que acelera las operaciones de matemáticas? No creo que pueda estirar a costosos (?) Compiladores de Intel. – user1055918

+0

@ user1055918: No en la parte superior de mi cabeza; las bibliotecas ICC son las únicas en Linux con las que tengo experiencia personal y me sentiría cómodo recomendando. Con suerte, alguien más puede indicarle una buena dirección. –

0

la diferencia en el número de ciclos de CPU es solo del 30%. Dado que no sabemos exactamente qué código generó el compilador, no diría que es absurdo. La mayor parte de la ganancia de rendimiento con su nueva CPU es la cantidad de núcleos, y su código no hace uso de eso.

También puede ser interesante intentar y desenrollar el ciclo. La relación de velocidad puede cambiar.

int main() { 
    double res0 = 0.0;   
    double res1 = 0.0;   
    double res2 = 0.0;   
    double res3 = 0.0;   
    double res4 = 0.0;   
    for(int i=1; i<200000000; i+=5) { 
      res0 += exp((double) 100.0/i); 
      res1 += exp((double) 100.0/(i+1)); 
      res2 += exp((double) 100.0/(i+2)); 
      res3 += exp((double) 100.0/(i+3)); 
      res4 += exp((double) 100.0/(i+4)); 
    } 
    double res=res0+res1+res2+res3+res4; 
    printf("%lf", res); 
    return(0); 
} 
+3

Su ciclo "desenrollado" realmente cambia el comportamiento debido a que la adición no es asociativa. –

+0

Si desea probar este tipo de cosas, será mejor que se mueva directamente a OpenMP, gcc lo implementa bien. Lo intenté y me da una aceleración de 3.29. –

+0

@R ..: excelente observación! –

1

intente encender la opción -ffast-math. Esto podría darle una implementación menos pedante y correcta de exp(). La pregunta entonces es si desea la respuesta potencialmente incorrecta que puede producir.

Cuestiones relacionadas