Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Uso 100% CPU para un programa hecho en c++

Estas en el tema de Uso 100% CPU para un programa hecho en c++ en el foro de C/C++ en Foros del Web. Hola amigos, les traigo un problema muy interesante. Me dí cuenta que el algoritmo que estoy desarrollando tardaba mucho, así que tuve la idea de ...
  #1 (permalink)  
Antiguo 12/08/2014, 21:05
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Uso 100% CPU para un programa hecho en c++

Hola amigos, les traigo un problema muy interesante.

Me dí cuenta que el algoritmo que estoy desarrollando tardaba mucho, así que tuve la idea de probar que tan eficiente era c++, para ello construí un programa aparte, muy simple que lo muestro a continuación:

Código C++:
Ver original
  1. #include <ctime>    //reloj
  2. #include <iostream>
  3. #include <math.h>
  4.  
  5. using namespace std;
  6.  
  7. void mostrarTiempo(clock_t tiempo);
  8.  
  9. int main(){
  10.     clock_t tiempo = clock();    //iniciar el reloj
  11.     long long i = 0;
  12.     double sum = 0;
  13.     for (i = 1; i < 10000000000; i++){
  14.         sum = sum + log(double(i));
  15.     }
  16.  
  17.     mostrarTiempo(tiempo);
  18.  
  19.     cout << "Pulse para salir...";
  20.     cin.sync();
  21.     cin.get();
  22.     return 0;
  23. }
  24.  
  25.  
  26. void mostrarTiempo(clock_t tiempo){
  27.     tiempo = clock() - tiempo;
  28.     cout << endl << "Tiempo de ejecución es " << double(tiempo) / CLOCKS_PER_SEC << " seg." << endl;
  29. }

Como pueden ver sólo es un for muy largo, para mi sorpresa que el tiempo era de 340 segundos (que en otros equipos es de 140 por ejemplo) y mirando mi administrador de tareas, en la pestaña rendimiento, sólo se le da un 17% de uso de cpu en promedio a mi proceso (el programa compilado en c++), el uso total mientras lo hacia era de 45% en promedio, con windows y otras cosas.

Mi pregunta es como hacer para que windows le dedique todo lo que pueda al programa .exe que generé. Es decir que corriendo mi programa este casi al 100% del uso del cpu.

Muchas gracias.
  #2 (permalink)  
Antiguo 13/08/2014, 00:32
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Uso 100% CPU para un programa hecho en c++

Que use más CPU no quiere decir que tenga mayor rendimiento. Un algoritmo o programa tiene mayor rendimiento cuando hace una tarea en menos tiempo y con menos recursos.
__________________
Aviso: No se resuelven dudas por MP!
  #3 (permalink)  
Antiguo 13/08/2014, 00:57
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Uso 100% CPU para un programa hecho en c++

Buenas,

Eso es porque tu programa se ejecuta en un solo nucleo de tu procesador.

Si quieres utilizar varios nucleos, tienes que desarrollar pensando en ello. Deberas cambiar tu algoritmo para que divida la tarea y la ejecute en diversos threads, ya sea directamente o con ayuda de alguna libreria como openmp.

Te dejo un link muy interesante para lograr paralelismo:
http://gribblelab.org/CBootcamp/A2_Parallel_Programming_in_C.html


Un saludo
  #4 (permalink)  
Antiguo 13/08/2014, 02:31
Avatar de Malenko
Moderador
 
Fecha de Ingreso: enero-2008
Mensajes: 5.323
Antigüedad: 16 años, 3 meses
Puntos: 606
Respuesta: Uso 100% CPU para un programa hecho en c++

El paralelismo no siempre se puede usar. Aquí estás siempre dependiendo del valor anterior para calcular el siguiente. Es decir, estarias trabajando con varios threads usando una variable compartida y a la que han de acceder de forma exclusiva. Si, va a subir el consumo de CPU pero porque son operaciones que son costosas, no porque aumente el rendimiento.
__________________
Aviso: No se resuelven dudas por MP!
  #5 (permalink)  
Antiguo 13/08/2014, 03:52
 
Fecha de Ingreso: julio-2006
Ubicación: Barcelona
Mensajes: 244
Antigüedad: 17 años, 9 meses
Puntos: 32
Respuesta: Uso 100% CPU para un programa hecho en c++

Cita:
Iniciado por Malenko Ver Mensaje
El paralelismo no siempre se puede usar. Aquí estás siempre dependiendo del valor anterior para calcular el siguiente. Es decir, estarias trabajando con varios threads usando una variable compartida y a la que han de acceder de forma exclusiva. Si, va a subir el consumo de CPU pero porque son operaciones que son costosas, no porque aumente el rendimiento.
No tengo mucha experiencia en programación concurrente pero que el programa, tal como este construido, dependa del valor anterior, no quiere decir que se pueda contruir otro que haga lo mismo de otra manera. Pues al final, el programa parece que lo que hace es calcular un sumatorio de los logaritmos de 1 a 9999999999. Cada hilo podría encargarse de calcular partes del sumatorio, independientemente uno del otro y al terminar, sumarlo en una variable, accediendo de forma exclusiva.

Un saludo!
__________________
github.com/xgbuils | npm/xgbuils
  #6 (permalink)  
Antiguo 13/08/2014, 05:48
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Uso 100% CPU para un programa hecho en c++

Buenas,

La verdad es que he considerado que el algoritmo publicado es una prueba y no el real.

De cualquier forma, tal y como apunta Pantalaimon, la operacion se puede fraccionar, calcular concurrentemente y sumar los resultados al final. No existe aqui ningun problema, aunque estoy de acuerdo en que el paralelismo en muchos casos causa mas problemas que los que resuelve si no tenemos cuidado.

En cualquier caso lo unico que queria indicar es que el bajo uso de CPU se debe a la arquitectura multinucleo de los procesadores modernos y que solo se puede mejorar el rendimiento usando paralelismo. Eso no quita que si una operacion es muy costosa en calculo, entonces puede llevar mucho tiempo, no hay milagros. Un buen algoritmo no es aquel que dura poco, sino aquel que escala bien, en proporcion constante, lineal o logaritmica.


Un saludo
  #7 (permalink)  
Antiguo 13/08/2014, 10:29
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: Uso 100% CPU para un programa hecho en c++

Hola, muchas gracias por sus respuestas. En resumen se supone que el bajo consumo es debido a que se usa un sólo núcleo de los que tiene, por cierto tengo un i7, la verdad supuse eso y estuve monitorizando el uso de los núcleos con el programa everest, y realmente ningún núcleo estaba a tope. Como interpretar eso?, lo más obvio es que no es cuestión de que uso sólo un núcleo pero no estoy seguro.

Con el motivo de tener más información de esto me gustaría que ustedes prueben el código que les dí para comparar los resultados. El formato de reportar podría ser este:

CPU: intel core i7-2670QM @ 2.20 GHz
ram: 16gb
windows 8.1 64x
Tiempo del algoritmo: 286.656seg

Gracias.
  #8 (permalink)  
Antiguo 13/08/2014, 13:46
Avatar de Profesor_Falken  
Fecha de Ingreso: agosto-2014
Ubicación: Mountain View
Mensajes: 1.323
Antigüedad: 9 años, 8 meses
Puntos: 182
Respuesta: Uso 100% CPU para un programa hecho en c++

Pues la verdad es que no se como lo has medido...

En mi caso, en Ubuntu 14.04, ejecutando el programa en un i5 con 4 CPU: la CPU1, CPU3 y CPU4 están al 3-4%, mientras que la CPU2 está a 100% todo el rato.


Un saludo
  #9 (permalink)  
Antiguo 13/08/2014, 13:56
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: Uso 100% CPU para un programa hecho en c++

Cita:
Iniciado por Profesor_Falken Ver Mensaje
Pues la verdad es que no se como lo has medido...

En mi caso, en Ubuntu 14.04, ejecutando el programa en un i5 con 4 CPU: la CPU1, CPU3 y CPU4 están al 3-4%, mientras que la CPU2 está a 100% todo el rato.


Un saludo
Gracias, usaste el código de c++ que dí?, cuanto tiempo de ejecución obtuvo?.
  #10 (permalink)  
Antiguo 16/08/2014, 14:28
 
Fecha de Ingreso: junio-2014
Mensajes: 144
Antigüedad: 9 años, 10 meses
Puntos: 1
Respuesta: Uso 100% CPU para un programa hecho en c++

Hola, gracias por todas respuestas. Luego de indagar y buscar la respuesta si era la ya expuesta en este foro, la cantidad de nucleos que trabajan simultáneamente, es decir los threads o hilos de procesamiento. Programando con 8 threads el cpu va a 100%.

A quién le interese voy a adjuntar el código del for inicial, pero para que se realice con threads, el número de threads se define en la variable: "nucleos". Además uso una barrera para que haya problemas mientras los threads trabajan simultáneamente.

Código C++:
Ver original
  1. #include <ctime>    //reloj
  2. #include <iostream>
  3. #include <math.h>
  4. #include <thread>
  5. #include <vector>
  6. #include <mutex>
  7. using namespace std;
  8. static mutex barrier;
  9.  
  10. void mostrarTiempo(clock_t tiempo);
  11. vector<long long> bounds(long long parts, long long mem);
  12. void contar(double& sum, long long i, long long j);
  13.  
  14. int main(){
  15.     clock_t tiempo = clock();    //iniciar el reloj
  16.     int nucleos = 8, i = 0;
  17.     long long numerote = 0;
  18.     //numerote = 1000000;
  19.     numerote = 10000000000;
  20.     double sum = 0, sum1 = 0;
  21.     vector<thread> vNucleos;
  22.     vector<long long> limits = bounds(nucleos, numerote);
  23.     if (limits[0] == 0) limits[0] = 1;
  24.     for (i = 0; i < nucleos; i++){
  25.         vNucleos.push_back(thread(contar, ref(sum), limits[i], limits[i + 1]));
  26.     }
  27.     for (auto &t : vNucleos){
  28.         t.join();
  29.     }
  30.    
  31.     cout << endl << " " << sum << endl;
  32.     mostrarTiempo(tiempo);
  33.    
  34.     for (i = 1; i < numerote; i++){
  35.         sum1 = sum1 + log(double(i));
  36.     }
  37.     cout << endl << " " << sum1 << endl;
  38.    
  39.  
  40.     cout << "Pulse para salir...";
  41.     cin.sync();
  42.     cin.get();
  43.     return 0;
  44. }
  45.  
  46.  
  47. void mostrarTiempo(clock_t tiempo){
  48.     tiempo = clock() - tiempo;
  49.     cout << endl << "Tiempo de ejecución es " << double(tiempo) / CLOCKS_PER_SEC << " seg." << endl;
  50. }
  51. void contar(double& sum, long long i, long long j){
  52.     long long k; double sumar = 0;
  53.     for (k = i; k < j; k++){
  54.         sumar = sumar + log(double(k));
  55.     }
  56.     lock_guard<mutex> block_trheads_until_Finish_this_job(barrier);
  57.     sum = sum + sumar;
  58. }
  59. vector<long long> bounds(long long parts, long long mem){
  60.     vector<long long>bnd;
  61.     long long delta = mem / parts;
  62.     long long reminder = mem % parts;
  63.     long long N1 = 0, N2 = 0;
  64.     bnd.push_back(N1);
  65.     for (long long i = 0; i < parts; ++i) {
  66.         N2 = N1 + delta;
  67.         if (i == parts - 1)
  68.             N2 += reminder;
  69.         bnd.push_back(N2);
  70.         N1 = N2;
  71.     }
  72.     return bnd;
  73. }

Etiquetas: rendimiento
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:31.