9
votes

Comment garder l'utilisation de la CPU vers le bas lorsque vous exécutez un programme SDL?

J'ai fait une fenêtre très basique avec SDL et je veux continuer à fonctionner jusqu'à l'appui de la fenêtre X à la fenêtre.

#include "SDL.h"
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main(int argc, char **argv)
{
    SDL_Init( SDL_INIT_VIDEO );
    SDL_Surface* screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 0, 
                                            SDL_HWSURFACE | SDL_DOUBLEBUF );
    SDL_WM_SetCaption( "SDL Test", 0 ); 
    SDL_Event event;
    bool quit = false;
    while (quit != false)
    {
        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                quit = true;
            }
        }
        SDL_Delay(80);
    }
    SDL_Quit();
    return 0;
}


0 commentaires

4 Réponses :


3
votes

Pour vraiment comprendre cela, vous devez comprendre le filetage. Dans une application filetée, le programme fonctionne jusqu'à ce qu'il attend quelque chose, puis il indique au système d'exploitation que quelque chose d'autre peut courir. En substance, vous le faites avec la commande sdl_delay . S'il n'y avait pas de retard du tout, je soupçonne que votre programme fonctionnerait à une capacité de près de 100%.

La quantité de temps que vous devriez mettre dans la déclaration de retard ne compte que si les autres commandes prennent une durée importante. En général, je voudrais mettre le retard comme un temps similaire qu'il faut pour tester la commande de sondage, mais pas plus que, par exemple, 10 ms. Ce qui va arriver, c'est que le système d'exploitation attendra au moins cette durée, permettant aux autres applications de fonctionner en arrière-plan.

sur ce que vous pouvez faire pour améliorer cela, eh bien, on dirait qu'il n'y a pas beaucoup de choses que vous pouvez faire. Toutefois, notons que s'il y avait un autre processus, il y avait un autre processus en prenant une quantité importante de pouvoir de la CPU, la part de votre programme diminuerait.


4 commentaires

Est-il normal dans SDL d'utiliser un seul fil? Vous avez sdl_pushevent et sdl_addtimer , alors pourquoi ne pas aller multithreadé?


L'utilisation de 10 ms prend l'utilisation de la CPU à près de 60%. Je suis curieux de savoir comment GTK gère cela comme créant une fenêtre factice similaire avec elle n'affecte pas le total de la CPU.


@Dyp même si le programme n'est pas enfilé, le système d'exploitation est. Le système d'exploitation est responsable de la mesure de la consommation de la CPU, de sorte qu'il signalera plus haut qu'elle aurait autrement.


Passer un certain temps à l'interrogation d'une boucle de message de 1000 / x MS n'est qu'un gaspillage de temps (CPU). Dormir une quantité de temps constante ( sdl_delay ) est imho non une bonne solution dans la plupart des cas (presque tous) - que la synchronisation d'autre est-elle? Le seul cas qui me vient à l'esprit pourquoi vous ne voudrez pas dormir indéfiniment est des tâches régulières. Et vous pouvez utiliser un autre fil ou même sdl_addtimer pour le faire.



11
votes

Je voudrais certainement expérimenter des fonctions entièrement bloquantes (telles que sdl_waititevent ). J'ai une application OpenGL à Qt et j'ai remarqué que l'utilisation de la CPU planant entre 0% et 1%. Il pointe peut-être 4% pendant la "utilisation" (déplacement de la caméra et / ou provoquant des animations).

Je travaille sur ma propre boîte à outils de fenêtres. J'ai remarqué que je peux obtenir une utilisation similaire de la CPU lorsque j'utilise des boucles d'événement bloquant. Cela compliquera les minuteries que vous pourriez compter, mais il n'est pas terriblement difficile de mettre en œuvre des minuteries avec cette nouvelle approche.


0 commentaires

7
votes

Je viens de comprendre comment réduire l'utilisation du processeur dans mon jeu de 50% à moins de 10%. Votre programme est beaucoup plus simple et simplement en utilisant sdl_delay () devrait suffire.

Qu'est-ce que j'ai fait était: Utilisez sdl_displayformat () lors du chargement d'images, le blittement serait plus rapide. Cela a apporté son utilisation de la CPU jusqu'à environ 30%.

Alors j'ai découvert que blâmer le fond des jeux (un gros fichier .png) mangeait le meilleur de mon processeur. J'ai cherché Internet pour une solution, mais tout ce que j'ai trouvé était la même réponse - il suffit d'utiliser sdl_delay () . Enfin, j'ai découvert que le problème était embarrassant simple - le sdl_displayformat () convertirait mes images 24 bits en 32 bits. J'ai donc mis mon écran BPP à 24, qui a amené l'utilisation du processeur à ~ 20%. La ramener à 16 bits a résolu le problème pour moi et l'utilisation de la CPU est de moins de 10% maintenant.

Bien sûr, cela signifie une perte de détails de couleur, mais comme mon jeu est un jeu 2D simpliste avec des graphiques non trop détaillés, c'était OK.


0 commentaires

14
votes

Je sais que c'est un article plus ancien, mais je suis moi-même survenu sur cette question avec SDL lors du démarrage d'un petit projet de démonstration. Comme l'utilisateur 'thebuzzsaw' a noté, la meilleure solution consiste à utiliser sdl_waitevent code> pour réduire l'utilisation de la CPU de votre boucle d'événement.

Voici comment il ressemblerait à votre exemple pour toute personne à la recherche d'une solution rapide à dans le futur. J'espère que cela aide! P>

#include "SDL.h"
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

int main(int argc, char **argv)
{
    SDL_Init( SDL_INIT_VIDEO );
    SDL_Surface* screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 0, 
                                            SDL_HWSURFACE | SDL_DOUBLEBUF );
    SDL_WM_SetCaption( "SDL Test", 0 ); 
    SDL_Event event;
    bool quit = false;
    while (quit == false)
    {
        if (SDL_WaitEvent(&event) != 0) {
            switch (event.type) {
            case SDL_QUIT:
            quit = true;
            break;
            }
        }
    }
    SDL_Quit();
    return 0;
}


0 commentaires