Thread: Solutions for slow performance?

  1. #16
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oooh, really? I never knew that Then again, I never did read the manual from cover to cover.

    Then there is another option I think somewhere around the "compile , exexcute, link" stuff
    And this option is for?....


    FrenchFry,

    Yes, I've heard that somewhere before... yet the memory is distant... elusive.... almost as if the last time I heard it was millions of milliseconds ago...

    Actually, I decided to use GDI because I needed to learn how to use it anyways At the time I'd only started learning c++ about a month ago, and I'd gotten my introduction to it in a particularly gruelling 'course' where I sat and copied the code to make a 3D game engine with DirectX8, with only a few weeks' experience in C, a couple months' experience in Java, and a few days' experience with Pascal. So I pretty much had to figure out how to make things show up on the screen as I went along
    Last edited by Hunter2; 08-20-2002 at 07:01 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #17
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Originally posted by Hunter2
    Oooh, really? I never knew that Then again, I never did read the manual from cover to cover.


    And this option is for?....


    FrenchFry,

    Yes, I've heard that somewhere before... yet the memory is distant... elusive.... almost as if the last time I heard it was millions of milliseconds ago...
    As I've been complaining, my visual studio installation is hosed so I can't tell you exactly where the options are. So first you go and enable profiling. Then around where the compile etc stuff is, there is the actual command for performing the profiling. Thats what I meant.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #18
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Oh, I see Thanks!
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #19
    Registered User JoshG's Avatar
    Join Date
    Mar 2002
    Posts
    326
    Wow, just played the new version, best damn space shooter game I have played with GDI. Well, the only one, but is is good. The homing missiles are awsome, but they seem to slow the game down.

  5. #20
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    JoshG,

    Yep, they do slow the game down... more's the pity, since there seems to be not much I can do about it other than to try speeding up the rest of the game


    MrWizard,

    I just did the profiler thing, and guess what I found out??! 3 lines of code make up 59% of the running time! These three would be:
    Code:
    BitBlt(dcFront, 0, 0, scrnRect.right, scrnRect.bottom, dcBack, 0, 0, SRCCOPY);
         if(clearBackDC)
              FillRect(dcBack, &scrnRect, blackBrush);
    Unfortunately, this is where the backbuffer gets blitted to the screen. And unless I have the FillRect(), nothing will get erased (save perhaps the stars, which I can make erase themselves)... and I can't think of a way to make the stuff erase themselves without leaving a black shadow behind. Any suggestions?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #21
    Pursuing knowledge confuted's Avatar
    Join Date
    Jun 2002
    Posts
    1,916
    I didn't actually read through the code that you posted, but I would just like to note that someone commented that you should use a shift instead of a divide by two, but if it is on floats, you can't shift floats, don't even try it.
    Away.

  7. #22
    Registered User JoshG's Avatar
    Join Date
    Mar 2002
    Posts
    326
    When you use FillRect are you clearing the buffer? You do not need to do that if you are going to write over everything. I remember you saying you are drawing individual stars now, so you might have to, unless in your CStar class you have a Erase() that erases the few pixels a star takes up. Then instead of FillRect, you could have

    Code:
    for(int i = 0; i < NumOfStars; i++)
      Stars[i].Erase();
    
    Ship.Erase()
    Umm, it makes sense to me . You would have to do that before you update the ships coordinates and such, or it would erase them at there new coordinates.

  8. #23
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Blackrat, I did a search through "all open documents" for "/ 2", and replaced them all with >> 1 (with a comment explaining what I was doing). No problems arose ('cuz they were all ints), but it didn't speed up... well, it probably did, just not enough to notice. Oh well, better than nothing!

    JoshG,

    Oh right, I never thought about it that way Each star only takes 1 pixel, in order to minimize the number of SetPixelV's (actually, I tried making stars random-sized but then it looked like the aliens had a really bad dandruff problem ). And earlier, I made the stars set their pixel to black before setting a new pixel, but I commented it out when I found out everything was getting erased anyways Then I thought of making each graphics object (in it's draw() function) erase itself, then draw itself at the new position. Only problem with that was that anything that got drawn earlier on top of the old position would get erased too, resulting in the "black shadow" I was talking about. But come to think of it, I could just erase() each object at the start, then move them and draw them instead of erasing them in the draw() part... Thanks for the inspiration
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #24
    Registered User JoshG's Avatar
    Join Date
    Mar 2002
    Posts
    326
    Your welcome It is not too hard, as long as you have every object erase itself, then update the coords and such, then have them all redraw themselves.

  10. #25
    Visionary Philosopher Sayeh's Avatar
    Join Date
    Aug 2002
    Posts
    212
    Well, the first mistake is C++. I'm not being funny-- it's true. The language is fine, but compilers aren't really "there" yet with C++, so it runs a lot slower than C.

    Here are some tips that will help you, even with C++:

    x touch each pixel once.
    x don't touch pixels you don't have to.
    x Trade RAM for speed.
    x Don't allocate and deallocate a lot.
    x Don't call functions a lot, use macros.
    x If you call functions, don't pass lots of args (stack time)
    x Use global variables instead of local ones (stack time)
    x Use long-words even when not needed (native cpu sizing)
    x Make pixmaps long-word aligned in dimensions
    x limit yourself to 8-bit color, initially
    x unroll some loops
    x minimize tests (whiles, loops, ifs, dos)
    x minimize decisions, particularly in high-repetition code
    x user register variables appropriately
    x use tables.

    Essentially, the whole idea behind optimization is to minimize the amount of time wasted in your code, and maximize the amount of time it's actually getting something done.

    Another thing, reexamine your routines and look for relationships in how things work. Reorganizing your data, and/or redesigning algorithms to take advantage of naturally occurring optimizations can make a huge difference.
    It is not the spoon that bends, it is you who bends around the spoon.

  11. #26
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Thanks alot! I'll look through my code with this checklist But what does 'touch each pixel once' mean?

    *also, I looked up the register keyword on MSDN, and this is what it said:

    The 32-bit compiler does not honor user requests for register variables. Instead it makes its own register choices when global optimizations are on. However, all other semantics associated with the register keyword are honored by the 32-bit compiler.

    What are 'all other semantics'? At the bottom of the page, it said 'For more information, see: auto, extern, and static'. Are those supposed to be the 'other semantics'?
    Last edited by Hunter2; 08-21-2002 at 03:12 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  12. #27
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Those were some pretty good ideas on optimizations. Also, your comment about C vs. C++ as far as speed goes kind of bothered me. Now, when you get into inheritance and all that garbage yes speed can drastically be affected. However, in this game I didn't see a lot of this and from my own experience on simple programs C and C++ are about the same. In fact, in C standard input/output usually everything gets included were in C++ it is smart enough with streams to only include what is needed. Also the register keyword. I think visual studio is smart enough to use these were needed on its own so that is not really a huge deal. I agree with most of your other statements especially don't allocate and deallocate a lot, you want to just allocate a lot in the beginning and pull memory from that. Use macros instead of functions? Well I guess it really depends on what you doing with the function. If you really need typeless functions I would write a macro but I don't think the speed difference is that much between inline functions and macros. I could be wrong on some things I said above but I'm fairly sure they are dead on.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  13. #28
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    I have not looked over your code. But I can tell you that IO operations are always several orders of magnitude slower than calculations. But I guess you already discovered that. Rendering in general is slow on pre-gigahertz machines, so limit the time spent drawing backgrounds. Another significant improvement can be achieved with separate threads of execution. If you would like a simple library to begin with, just PM or email me. But beware. Threads can cause a lot of headaches and often require severe restructuring of the program. Nonetheless, giving each sprite it's own thread makes the game flow more naturally, and this is one of the main advantages of using them.


    Macros are indeed ugly, but they ARE faster. Try this simple test:


    Code:
    
    double mult( double a, double b){ return a * b; }
    
    #define MULT(a, b) ((a)*(b))
    
    int main() {
    
    time_t start, stop;
    
    double iter, x = 1, y = 3;
    
    start = clock();
    
    for(iter = 0; iter < 100000000; iter++)
    x = mult(x, y);
    
    stop = clock();
    
    printf("(Function) Result: %d Seconds Elapsed\n\n", (stop-start)/1000);   
    
    //...48 - 52 seconds on my machine...
    
    
    
    x = 1, y = 3;
    
    start = clock();
    
    for(iter = 0; iter < 100000000; iter++)
    x = MULT(x, y);
    
    stop = clock();
    
    printf("(MACRO) Result: %d Seconds Elapsed\n\n", (stop-start)/1000);
    
    //...35 - 38 seconds on my machine...
    
    
    getch();
    
    return 0;
    }

    On my system, the macro was roughly 20%-30% faster.

    BTW:

    Don't waste your time with FillRect(), you can get by without it.

    Oh, and far as speed goes, DirectX and OpenGL have much faster bit-block transfers than BitBlt().

    Anyway, good luck on the game!
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  14. #29
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Thanks.... mm hmm, check out this code right here that crashed my comp cuz it took too much memory:

    Code:
    std::vector<char> vector;
    
    while(ppl.tellMeThat())
    {
         vector.push_back('A');
    }


    I already cut out the FillRect(), dunno how much it improved performance... but it has made some stuff not erase properly. Oh well, hope it helps some. I've decided to quit this game, and try converting it over to DirectX (next destination).

    Everybody, the game is now officially done! Unless somebody wants to take the source and add to it, that is. You can use the link in the sig if you want to try the game out or look at the source. Thanks for all the help everyone!

    (p.s. I still haven't figured 1 thing out, and that's about a vector of pointers... doesn't affect anything though, except maybe a little bit of a memory leak so I don't really care.)
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  15. #30
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    "...except maybe a little bit of a memory leak so I don't really care..."
    You should though!
    Anyway, the vector itself will deallocate. But if you allocated an object, then pushed it into the vector, indeed you must deallocate each object. One way to do that is to create a derived class of vector which dynamically deallocates when the ~destructor() is called...


    std::vector<char> vector;

    while(ppl.tellMeThat())
    {
    vector.push_back('A');
    }

    Any program can crash if it allocates too much memory. Haven't you seen 'moi's sig?:
    for(; malloc(1000);
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Performance and footprint of virtual function
    By George2 in forum C++ Programming
    Replies: 8
    Last Post: 01-31-2008, 07:34 PM
  2. File map performance
    By George2 in forum C++ Programming
    Replies: 8
    Last Post: 01-04-2008, 04:18 AM
  3. Observer Pattern and Performance questions
    By Scarvenger in forum C++ Programming
    Replies: 2
    Last Post: 09-21-2007, 11:12 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. inheritance and performance
    By kuhnmi in forum C++ Programming
    Replies: 5
    Last Post: 08-04-2004, 12:46 PM