SpiderPig Posted January 22, 2023 Share Posted January 22, 2023 I've created a memory pool for voxel nodes rather than call new and delete for every single octree cell. Everything appears to work correctly I'm just a bit confused with what VS tells me about the memory used. It doesn't go down when cells are deleted, I've also placed GetMemoryUsage() before and after the delete keywords to test if there is a difference but most of the time there is not - if there is it has gone up not down. Not sure if it takes time to process the memory change or not? Pages are definitely being deleted and created when they should be, memory goes up only when new pages are created after it uses the existing memory allocated in previous pages. But the memory never goes down. Release is the same. I read that delete simply says to the OS that it can use that memory location for something else now and that technically your data could still be there if it hasn't been overridden. Have I done anything stupidly wrong? Header.h struct VoxelPage { VoxelNode* nodes = nullptr; VoxelPage() {} ~VoxelPage() { delete[] nodes; } }; class VoxelPages { private: uint64_t page_index = 0, page_total = 0; uint64_t voxel_index = 0; uint64_t size = 0, page_size = 0; VoxelPage** pages = nullptr; public: VoxelPages(uint64_t size); ~VoxelPages(); void Reset(); void Clean(); void Destroy(); VoxelNode* GetVoxelNode(); }; Source.cpp VoxelPages::VoxelPages(uint64_t size) { this->size = size; page_size = size * size; pages = new VoxelPage*[size]; for (int id = 0; id < size; id++) { pages[id] = nullptr; } pages[0] = new VoxelPage(); pages[0]->nodes = new VoxelNode[page_size]; page_total++; } VoxelPages::~VoxelPages() { Destroy(); } void VoxelPages::Reset() { page_index = 0; voxel_index = 0; } void VoxelPages::Clean() { for (auto id = page_index + 1; id < page_total; id++) { delete pages[id]; pages[id] = nullptr; } page_total = page_index + 1; } void VoxelPages::Destroy() { for (int id = 0; id < page_total; id++) { delete pages[id]; } delete[] pages; } VoxelNode* VoxelPages::GetVoxelNode() { auto node = &pages[page_index]->nodes[voxel_index]; voxel_index++; if (voxel_index == page_size) { voxel_index = 0; page_index++; if (page_index >= page_total) { pages[page_index] = new VoxelPage(); pages[page_index]->nodes = new VoxelNode[page_size]; page_total++; if (page_total == size) { Notify("VoxelPages::GetVoxelNode() : page_total exceeds size!", "Error", true); } } } return node; } Quote Link to comment Share on other sites More sharing options...
Josh Posted January 23, 2023 Share Posted January 23, 2023 I usually use shared pointers so I don't even have to worry about leaks most of the time. You also need to consider that other threads that are running may be allocating memory. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
SpiderPig Posted January 23, 2023 Author Share Posted January 23, 2023 I did start off using shared pointers but through a few simple tests found that raw pointers were faster. I wrote a small console app to test it and it is working perfectly. #include "Header.h" int main() { int component_size = 256; VoxelPages* pages = new VoxelPages(component_size); auto i = sizeof(VoxelNode); auto e = 128 * 128 * 128; for (int i = 0; i < e; i++) { auto my_node = pages->GetVoxelNode(); } delete pages; while (true) { } } First off only the graph shows the current memory used, the number at the top right seems to be the max used so far. If this is working, that means I have a memory leak somewhere else. Quote Link to comment Share on other sites More sharing options...
Canardia Posted January 23, 2023 Share Posted January 23, 2023 Not sure, but according to this description, auto variables are slower and constantly reserve and release memory than statically typed variables - even if both are resolved at compile time: What is the difference between an auto and non auto variable? Automatic variables create a new each time when program's execution enters in the function and destroys when leaves. Static variable create once, when program's execution enters in the function first time, destroys when program's execution finishes, they do not again. I would always try to keep variable declarations before the iteration, just to be sure. 1 1 Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
SpiderPig Posted January 24, 2023 Author Share Posted January 24, 2023 Do you mean the auto keyword? I don't see how that would effect performance... but it's true, the my_node pointer in my example is going out of scope but the memory allocated in GetVoxelNode() remains untill I call : delete pages; Declaring variables inside a loop should generally be avoided if possible for performace reasons. But in this example speed of the allocation isn't a concern. 🙂 I can now see that the memory usage in VS diagnostic tools shows the maximum because that is the new range of the graph. I wonder if you can get it to display the current memory usage without hovering the mouse over it... Quote Link to comment Share on other sites More sharing options...
Solution SpiderPig Posted January 24, 2023 Author Solution Share Posted January 24, 2023 @Josh I decided to do what you told me too. I'm now using GetMemoryUsage() and it's displaying what it should. On another memory related topic "world->renderstats.vram" is the VRAM available and not in use, correct? Quote Link to comment Share on other sites More sharing options...
StOneDOes Posted January 24, 2023 Share Posted January 24, 2023 9 hours ago, SpiderPig said: I did start off using shared pointers but through a few simple tests found that raw pointers were faster. They will be, slightly, because you don't have the extra overhead. There isn't anything wrong with raw pointers so long as there is a clear memory management pattern, but may not work well amongst larger teams of developers. With smart pointers you won't have leaks, and generally it is the accepted practise. 9 hours ago, Canardian said: Not sure, but according to this description, auto variables are slower and constantly reserve and release memory than statically typed variables - even if both are resolved at compile time: What is the difference between an auto and non auto variable? Automatic variables create a new each time when program's execution enters in the function and destroys when leaves. Static variable create once, when program's execution enters in the function first time, destroys when program's execution finishes, they do not again. This has been taken out of context (a link to quoted source is ideal). What you're referring to is the 'auto' keyword used in C, not C++. It is just comparing static variable declaration vs non-static. In C++, the type where auto keyword is used is automatically deduced by the compiler at compile time, and has no impact on performance. Its true that static variables may be considered "faster" because your only initialzing them once, and destroying them once, but you'll often require logic to track their value. They have their purposes, but not overly common. 6 hours ago, SpiderPig said: Declaring variables inside a loop should generally be avoided if possible for performace reasons. That's not necessarily true. You'll find that the compiler will optimize this and the difference will likely not be measurable or even existent. 1 Quote Link to comment Share on other sites More sharing options...
Josh Posted January 24, 2023 Share Posted January 24, 2023 3 hours ago, SpiderPig said: On another memory related topic "world->renderstats.vram" is the VRAM available and not in use, correct? Yeah, it’s the total VRAM. The Vulcan memory allocator has some commands for fetching mem usage but they are complicated and I haven’t looked into it much yet 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.