Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Bajo rendimiento con C++

Iniciado por Eskema, 31 de Enero de 2009, 09:06:35 PM

« anterior - próximo »

Eskema

Muy buenas, hace un tiempo empeze a reciclarme de C a C++ y me encuentro con lo que para mi son graves problemas de rendimiento. Segun el administrador de tareas, mis juegos actuales en 2D hechos en C, apenas consumen entre un 2-4% de cpu, algo que pienso esta bien, o por lo menos me parece aceptable. El caso es que despues de crear clases y demas zarandajas de estas del c++ (sin usar apenas stl, ni usar vectores) el consumo de cpu ha subido a un 8-10%, lo cual me parece bastante mal, dado que desarrollo para la consola PSP, cualquier ganancia en cpu se traduce en algun fps mas y mas finura a la hora de jugar.
Complicando mas el codigo, he usado vectores para almacenar los objetos, usea algo asi
static std::vector<CActor*>   ActorList;
Donde los actores son los objetos que voy a usar en el juego, player, enemigos, etc, etc. Con esta "pequeña" burrada de almacenar los objetos en un vector para luego dibujarlo asi :
for(unsigned int i = 0;i < CActor::ActorList.size();i++) {
        if(!CActor::ActorList[i]) continue;

        CActor::ActorList[i]->DrawActor(Surf_Display);
    }


Ahora el consumo de cpu sube a 14%-20% lo cual me parece totalmente inaceptable, pero el caso es q el tutorial de loover de tetris tiene un consumo de cpu de un 20%, con lo cual no se q pensar.

¿Es algo normal este tipo de consumo? ¿se debe a una mala programacion? ¿el c++ es asi de malo frente al c?

Saludos,

AK47

Mis juegos tienen un consumo de CPU de 100% cuando no estan esperando al Vsync, ya que refrescan constantemente la pantalla (todo lo rapido que pueda la maquina). Mas que consumo de CPU mide el tiempo de calcular un frame para hacerte una idea mas aproximada del rendimiento de tus juegos :)

Pogacha

#2
Cita de: Eskema en 31 de Enero de 2009, 09:06:35 PM
Muy buenas, hace un tiempo empeze a reciclarme de C a C++ y me encuentro con lo que para mi son graves problemas de rendimiento. Segun el administrador de tareas, mis juegos actuales en 2D hechos en C, apenas consumen entre un 2-4% de cpu, algo que pienso esta bien, o por lo menos me parece aceptable. El caso es que despues de crear clases y demas zarandajas de estas del c++ (sin usar apenas stl, ni usar vectores) el consumo de cpu ha subido a un 8-10%, lo cual me parece bastante mal, dado que desarrollo para la consola PSP, cualquier ganancia en cpu se traduce en algun fps mas y mas finura a la hora de jugar.
Complicando mas el codigo, he usado vectores para almacenar los objetos, usea algo asi
static std::vector<CActor*>   ActorList;
Donde los actores son los objetos que voy a usar en el juego, player, enemigos, etc, etc. Con esta "pequeña" burrada de almacenar los objetos en un vector para luego dibujarlo asi :
for(unsigned int i = 0;i < CActor::ActorList.size();i++) {
        if(!CActor::ActorList[i]) continue;

        CActor::ActorList[i]->DrawActor(Surf_Display);
    }

Ahora el consumo de cpu sube a 14%-20% lo cual me parece totalmente inaceptable, pero el caso es q el tutorial de loover de tetris tiene un consumo de cpu de un 20%, con lo cual no se q pensar.
¿Es algo normal este tipo de consumo? ¿se debe a una mala programacion? ¿el c++ es asi de malo frente al c?

Es que esta mal hecho (en teoria)

Si usas una indexacion para referirte a un elemento estas haciendo matematica de punteros, en cambio si tienes en ves un iterator:
for(std::vector<CActor*>::iterator i=CActor::ActorList.begin(); i != CActor::ActorList.end(); ++i)
        if( (*i) )  (*i)->DrawActor(Surf_Display);


Esto deberia andarte mucho mas rapido (en teoria).

En teoria digo por dos razones:
1 - Si estas en debug, cada vez que haces una indexacion con los operadores [ ] se checkean rangos, pero esto no pasa en release.
2 - Si estas en modo release, el compilador se deberia dar cuenta de la indexacion progresiva y usar un puntero en vez de eso.

Ahora eso no deberia representar en realidad un bottleneck en el CPU, busca que el problema esta en otra parte.
Estudia bien la stl, pues mal usada es contraproducente, bien usada, no mejora el rendimiento pero si la productividad.

Saludos

davur

#3
Haz uso de un profiler para determinar qué areas del código están suponiendo un cuello de botella, si es que realmente las hay. Utilizar C++ no va a aumentar el consumo de CPU mágicamente. De hecho, si C++ (e incluyo la librería estándar) es tu cuello de botella es que no lo estás utilizando correctamente.

El trozo de código que has posteado (y que muy posiblemente no represente ninguna penalización relevante en el rendimiento de tu programa) no es la manera idiomática de recorrer un std::vector, como ya ha apuntado Pogacha [1] (otro pequeño detalle es que en este caso no es necesario llamar a end() en cada iteración).

La comprobación en cada iteración del bucle de que el elemento actual es no nulo no debería estar ahí. Llegado el momento de recorrer el vector, ya tendrías que tener la garantía de que los elementos son válidos. En cualquier caso, como norma general tampoco es idiomático utilizar punteros llanos en C++ porque no proporcionan ningún tipo de información acerca de la propiedad de la memoria reservada (exclusiva, compartida, ...). Normalmente, uno tiene algo similar a:


std::vector<boost::shared_ptr<Actor> > actors;

// ...

BOOST_FOREACH(boost::shared_ptr<Actor> a, actors)
{
    a->draw();
}


Otro detalle: ¿por qué CActor y no Actor? Escribir una C delante de cada nombre de clase no proporciona ninguna ventaja ni información de interés, y sí tiene varios inconvenientes. El más notable, que dificulta el seguimiento del código.

[1] Nótese que MSVC++, que es el compilador al que nos referimos, hace comprobaciones de rango tanto en iteradores como en el operador [], tanto en debug como en release, por defecto (en sus versiones más recientes): más información.

Eskema

Lo de Cactor no es mas q para saber que hablo de la clase actor. Entonces me olvido de la cpu y me centro mejor en los fps, a ver si hay diferencias apreciables usando unas cosas u otras, muchas senkius :)

AK47

Lo de modo debug es importante, con visual C++ segun como este configurado el asunto puede ir mas o menos igual que en release o arrastrarse como una economia de una republica-monarquica bananera  :D

Eskema

no uso visual c++, uso codeblocks y gcc 4.3 ;)






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.