Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Memory usage problem  (Read 2083 times)

0 Members and 1 Guest are viewing this topic.

zarro110

  • Newbie
  • *
  • Posts: 2
    • View Profile
Memory usage problem
« on: February 19, 2022, 06:18:23 pm »
Im am new to SFML and have made a simple program to draw a grid of squares and I was trying to measure performance. When I run this I can see the memory usage climb to above a gigabyte before dropping and rising again. What I don't understand is why this much memory is being allocated. It happens somewhere in the draw function. Do I have to free the Vertexarray in some way? If yes, how? (resizing to 0 doesn't help)


#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <vector>
#include <chrono>

class World {
public:
        std::vector<std::vector<int>> map;
        sf::Vector2i worldSize;
        std::vector<sf::Color> colors;

        World(int width, int height) {
                worldSize = sf::Vector2i(width, height);

                for (int x = 0; x < worldSize.x; x++) {
                        std::vector<int> temp;
                        for (int y = 0; y < worldSize.y; y++) {
                                temp.push_back(0);
                        }
                        map.push_back(temp);
                }
                colors.push_back(sf::Color::White);
                colors.push_back(sf::Color::Black);
        }

        void draw(sf::RenderWindow* screen) {
                sf::Vector2u screenSize = screen->getSize();
                sf::View view = screen->getView();
                sf::Vector2f viewCenter = view.getCenter();
                sf::Vector2f viewSize = view.getSize();

                float tileSize = 1;

                int x0 = 0;
                if ((viewCenter.x - (viewSize.x / 2)) > x0)
                        x0 = (viewCenter.x - (viewSize.x / 2));

                int x1 = worldSize.x;
                if ((viewCenter.x + (viewSize.x / 2)) + 1 < x1)
                        x1 = (viewCenter.x + (viewSize.x / 2)) + 1;

                int y0 = 0;
                if ((viewCenter.y - (viewSize.y / 2)) > y0)
                        y0 = (viewCenter.y - (viewSize.y / 2));

                int y1 = worldSize.x;
                if ((viewCenter.y + (viewSize.y / 2)) + 1< y1)
                        y1 = (viewCenter.y + (viewSize.y / 2)) + 1;

                int xSize = x1 - x0;
                int ySize = y1 - y0;
               
                if (xSize > 0 && ySize > 0) {
                        sf::VertexArray vertices;
                        vertices.setPrimitiveType(sf::Quads);
                        vertices.resize(xSize * ySize * 4);


                        for (int x = x0; x < x1; x += 1) {
                                for (int y = y0; y < y1; y += 1) {
                                        int current = (((x - x0) * ySize) + (y - y0)) * 4;
                                        vertices[current + 0].position = sf::Vector2f(x * tileSize, y * tileSize);
                                        vertices[current + 1].position = sf::Vector2f((x + 1) * tileSize, y * tileSize);
                                        vertices[current + 2].position = sf::Vector2f((x + 1) * tileSize, (y + 1) * tileSize);
                                        vertices[current + 3].position = sf::Vector2f(x * tileSize, (y + 1) * tileSize);


                                        vertices[current + 0].color = colors[map[x][y]];
                                        vertices[current + 1].color = colors[map[x][y]];
                                        vertices[current + 2].color = colors[map[x][y]];
                                        vertices[current + 3].color = colors[map[x][y]];
                                }
                        }

                        screen->draw(vertices);
                        vertices.resize(0);
                }
        }
};

int main()
{

        sf::Vector2f screenSize(500, 500);

        World myWorld(124, 124);

        sf::RenderWindow window(sf::VideoMode(screenSize.x, screenSize.y), "tileworld");
        window.setView(sf::View(sf::Vector2f(myWorld.worldSize) * 0.5f , sf::Vector2f(myWorld.worldSize) * (myWorld.worldSize.x / screenSize.x)));

        auto start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 100000; i++) {
                myWorld.draw(&window);
                std::cout << i << "\r";
        }
        auto stop = std::chrono::high_resolution_clock::now();
        std::cout << std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count()/100000 << std::endl;

        return 0;
}

 
« Last Edit: February 22, 2022, 05:11:54 pm by zarro110 »

kojack

  • Sr. Member
  • ****
  • Posts: 300
  • C++/C# game dev teacher.
    • View Profile
Re: Memory usage problem
« Reply #1 on: February 19, 2022, 10:32:39 pm »
What OS are you running this on and how are you measuring memory use?

Running it on my system (as a 64bit build on Win 10), Visual Studio's diagnostic tool (debug build) shows it sits on about 55MB.


Task Manager shows similar (around 49MB for release, 51+ for debug)

zarro110

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Memory usage problem
« Reply #2 on: February 20, 2022, 05:33:06 pm »
I am running it on Windows 10 and am programming with Visual Studio 2019. I dynamically linked SMFL following the tutorial on the site and everything works. This is what happens with a new project, using only the code posted above:



it does this both in debug and release. I use SFML-2.5.1  C++ 15 (2017) - 32-bit which I downloaded two days ago.
« Last Edit: February 20, 2022, 05:39:27 pm by zarro110 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Memory usage problem
« Reply #3 on: February 24, 2022, 07:17:49 pm »
Hard to say what exactly is going on, but it's not really SFML related.

You create a vector of vectors of ints. A vector needs to allocate contiguous memory, meaning all memory blocks need to be next to each other. This applies to the ints as well as the vector of ints.
My speculation would be that somehow the std::vector implementation causes the spike as it's trying to fulfill this requirement. And maybe a mix of being limited to 32-bits of addressable memory space.
But that's just a guess and might be completely wrong.

You could try and see how it plays out if you build your application as 64-bits. Or when comparing it to a release build. Or build SFML yourself for VS 2019 (or grab a snapshot build) so it can use the latest toolchain in combination.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kojack

  • Sr. Member
  • ****
  • Posts: 300
  • C++/C# game dev teacher.
    • View Profile
Re: Memory usage problem
« Reply #4 on: February 25, 2022, 08:42:37 am »
Good point, I'm on VS2022 with self built SFML from the repo, so things might have changed since VS2017.

In one of the older visual studios (maybe 2008 or 2010) the Ogre3D community discovered a memory leak in Microsoft's STL, every stream (string stream, file stream, etc) leaked 4 bytes. They were using temp string streams to format debug info (fps, tri count, etc) every frame for a gui panel, so that added up fast when the engine is running at 1000+fps. :)

 

anything