Trabajo en una institución científica y una de las tareas en las que estoy trabajando actualmente consiste en ejecutar simulaciones y generar los datos que produce sobre la marcha en el disco duro. Cuando digo "sobre la marcha", quiero decir que el programa mismo escupe datos en el disco cada segundo más o menos. Estas simulaciones están escritas exclusivamente en un solo hilo C ++ y se ejecutan en una Mac Pro. Las especificaciones relevantes de esta Mac son las siguientes:
OSX Version: 10.6.8
Model Name: Mac Pro
Model Identifier: MacPro4,1
Processor Name: Quad-Core Intel Xeon
Processor Speed: 2.66 GHz
Number Of Processors: 2
Total Number Of Cores: 8
Los Intel Xeon tienen hipertreflejos para hasta 8 núcleos virtuales
Ejecuto mis simulaciones en un archivo .sh simple, usando la siguiente sintaxis:
nohup simulation1.o configfile 2> /dev/null > /dev/null &
nohup simulation2.o configfile 2> /dev/null > /dev/null &
y así...
Usar nohup significa que no necesito preocuparme por desconexiones aleatorias cuando trabajo de forma remota.
Cuando miro ps
después de ejecutar, digamos 10, simulaciones usando mi archivo bash, encuentro que en la columna ESTADO, los procesos cambian regularmente de 'en ejecución' a 'atascado'. Además, esperaría que el uso de la CPU sea del 100% para cada proceso, pero cada proceso promedia aproximadamente el 28% cada uno. (Mi expectativa de que el uso de la CPU sea del 100% para cada proceso es que cuando ejecuto solo una de estas simulaciones, la columna de la CPU tiene un máximo de aproximadamente el 100%, lo que se suma al hecho de que los núcleos tienen hiperprocesamiento). Estas son simulaciones muy pesadas de la CPU .)
¿Alguien sabe lo que está pasando? Específicamente:
- ¿Qué significa "atascado" en relación con
ps
- ¿Por qué no se maximiza la CPU para cada proceso?
Agradecería mucho la ayuda.
Respuestas:
He arreglado mi problema. Resultó ser bastante sutil, pero gracias a Ozair le dio en el clavo. Mi simulación específica no lee muchos datos (solo los parámetros de inicialización) pero pasa mucho tiempo escupiendo datos calculados. La forma cruda que implementé originalmente, que involucra el c ++ estándar,
file.open("tobewritten.dat")
es muy lenta, incluso por sí sola, pero cuando se ejecutan varias instancias, las instancias individuales pasan años esperando 'tiempo de escritura' en el disco duro.Hay algunas lecciones específicas que he aprendido:
cout << std::endl
descarga el búfer en uso; Si el búfer no está lleno, entonces hay un uso menos que óptimo de la operación más rápida de escritura en RAM. Use"\n"
y luego cierre el archivo al final. c ++ maneja vaciar el búfer al disco cuando está lleno.Al escribir varios archivos de datos masivos (estoy hablando de GB) al mismo tiempo, es mejor especificar manualmente el búfer. Por el momento, he configurado el búfer a 50 MB. El uso de grandes buffers significa que su sistema pasa más tiempo entre la RAM y la CPU y solo se descarga en el disco (el bit lento) a intervalos de 50 MB
Ni siquiera lo use
cout
para escribir en el archivo. Es más lento quesprintf
y sus variantes.Usando los métodos que describí anteriormente, pasé del 28% de uso de CPU para cada proceso al 100% de uso de CPU. El ESTADO 'atascado' ya no aparece.
fuente