Optimizing Array add performance for large datasets

This commit is contained in:
Dynamitos
2020-03-16 13:29:17 +01:00
parent 3b55755f0c
commit 81b51d1c21
9 changed files with 101 additions and 8 deletions
+19 -1
View File
@@ -29,6 +29,7 @@ namespace Seele
assert(_data != nullptr);
for (int i = 0; i < size; ++i)
{
assert(i < size);
_data[i] = value;
}
refreshIterators();
@@ -174,7 +175,8 @@ namespace Seele
{
if (arraySize == allocated)
{
allocated += DEFAULT_ALLOC_SIZE;
uint32 newSize = arraySize + 1;
allocated = calculateGrowth(newSize);
void* tempArray = malloc(sizeof(T) * allocated);
assert(tempArray != nullptr);
std::memcpy(tempArray, _data, arraySize * sizeof(T));
@@ -247,6 +249,22 @@ namespace Seele
return _data[index];
}
private:
uint32 calculateGrowth(uint32 newSize) const
{
const uint32 oldCapacity = capacity();
if (oldCapacity > UINT32_MAX - oldCapacity / 2) {
return newSize; // geometric growth would overflow
}
const uint32 geometric = oldCapacity + oldCapacity / 2;
if (geometric < newSize) {
return newSize; // geometric growth would be insufficient
}
return geometric; // geometric growth is sufficient
}
void refreshIterators()
{
beginIt = Iterator(_data);
-1
View File
@@ -53,7 +53,6 @@ namespace Seele
int32 height;
const char* title;
bool bFullscreen;
PGraphics graphics;
};
class RenderCommandBase
@@ -7,12 +7,15 @@ Seele::VulkanAllocator::VulkanAllocator(PVulkanGraphics graphics)
heaps.resize(memProperties.memoryHeapCount);
for (size_t i = 0; i < memProperties.memoryHeapCount; i++)
{
std::cout << "Heap: Flags: " << memProperties.memoryHeaps[i].flags << " Size: " << memProperties.memoryHeaps[i].size << std::endl;
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
HeapInfo& heapInfo = heaps[i];
heapInfo.maxSize = memoryHeap.size;
}
for (size_t i = 0; i < memProperties.memoryTypeCount; i++)
{
VkMemoryType& type = memProperties.memoryTypes[i];
std::cout << "Memory Type: Properties" << type.propertyFlags << " on Index: " << type.heapIndex << std::endl;
HeapInfo& heapInfo = heaps[type.heapIndex];
heapInfo.types.add(type);
}
}
@@ -117,7 +117,27 @@ void Seele::VulkanGraphics::pickPhysicalDevice()
uint32 deviceRating = 0;
for (auto physicalDevice : physicalDevices)
{
uint32 currentRating = 0;
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties(physicalDevice, &props);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
currentRating += 100;
}
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
{
currentRating += 10;
}
if (currentRating > deviceRating)
{
deviceRating = currentRating;
bestDevice = physicalDevice;
}
}
this->physicalDevice = bestDevice;
}
void Seele::VulkanGraphics::createDevice()
{
}
@@ -22,6 +22,7 @@ namespace Seele
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
void pickPhysicalDevice();
void createDevice();
VkDevice handle;
VkPhysicalDevice physicalDevice;
+2 -2
View File
@@ -1,11 +1,11 @@
#include "Window.h"
#include "SceneView.h"
Seele::Window::Window(const WindowCreateInfo& createInfo)
Seele::Window::Window(const WindowCreateInfo& createInfo, PGraphics graphics)
: width(createInfo.width)
, height(createInfo.height)
, graphics(graphics)
{
graphics = createInfo.graphics;
center = new Section();
center->resizeArea(Rect(1, 1, 0, 0));
center->addView(new SceneView(graphics));
+1 -1
View File
@@ -53,7 +53,7 @@ namespace Seele {
class Window
{
public:
Window(const WindowCreateInfo& createInfo);
Window(const WindowCreateInfo& createInfo, PGraphics graphics);
~Window();
void beginFrame();
void endFrame();
+1 -1
View File
@@ -14,7 +14,7 @@ Seele::WindowManager::~WindowManager()
void Seele::WindowManager::addWindow(const WindowCreateInfo& createInfo)
{
PWindow window = new Window(createInfo);
PWindow window = new Window(createInfo, graphics);
windows.add(window);
}
+52
View File
@@ -1,5 +1,7 @@
#include "EngineTest.h"
#include "Containers/Array.h"
#include <time.h>
#include <chrono>
#define BOOST_TEST_MODULE SeeleEngine
#include <boost/test/unit_test.hpp>
@@ -110,6 +112,56 @@ BOOST_AUTO_TEST_CASE(random_access)
BOOST_CHECK_EQUAL(array[0], 4);
}
BOOST_AUTO_TEST_CASE(benchmark)
{
using namespace std::chrono;
srand(time(NULL));
const uint32 TEST_SIZE = 1024 * 256;
uint32* testSet = new uint32[TEST_SIZE];
#pragma loop( hint_parallel( 0 ) )
for (int i = 0; i < TEST_SIZE; ++i)
{
testSet[i] = rand();
}
high_resolution_clock::time_point start_vector = high_resolution_clock::now();
std::vector<uint32> vec;
for (int i = 0; i < TEST_SIZE; ++i)
{
vec.push_back(testSet[i]);
}
high_resolution_clock::time_point end_vector = high_resolution_clock::now();
float time_vector = duration_cast<milliseconds>(end_vector - start_vector).count();
std::random_shuffle(testSet, testSet + TEST_SIZE);
high_resolution_clock::time_point start_remove_vector = high_resolution_clock::now();
for (int i = 0; i < TEST_SIZE; ++i)
{
vec.erase(std::find(vec.begin(), vec.end(), testSet[i]));
}
high_resolution_clock::time_point end_remove_vector = high_resolution_clock::now();
float remove_vector = duration_cast<milliseconds>(end_remove_vector - start_remove_vector).count();
high_resolution_clock::time_point start_array = high_resolution_clock::now();
Array<uint32> arr;
for (int i = 0; i < TEST_SIZE; ++i)
{
arr.add(testSet[i]);
}
high_resolution_clock::time_point end_array = high_resolution_clock::now();
float time_array = duration_cast<milliseconds>(end_array - start_array).count();
high_resolution_clock::time_point start_remove_array = high_resolution_clock::now();
for (int i = 0; i < TEST_SIZE; ++i)
{
arr.remove(arr.find(testSet[i]), false);
}
high_resolution_clock::time_point end_remove_array = high_resolution_clock::now();
float remove_array = duration_cast<milliseconds>(end_remove_array - start_remove_array).count();
std::cout << "Vector: " << time_vector << "ms Array: " << time_array << "ms" << std::endl;
std::cout << "Vector remove: " << remove_vector << "ms Array remove: " << remove_array << "ms" << std::endl;
delete[] testSet;
}
BOOST_AUTO_TEST_SUITE_END()