Work on limiting maximum memory usage.

This commit is contained in:
David Williams 2014-09-18 14:51:43 +02:00
parent 38b8764129
commit 8dd026e095
4 changed files with 23 additions and 16 deletions

View File

@ -158,10 +158,8 @@ int main(int argc, char *argv[])
PerlinNoisePager* pager = new PerlinNoisePager(); PerlinNoisePager* pager = new PerlinNoisePager();
LargeVolume<MaterialDensityPair44> volData(PolyVox::Region::MaxRegion, pager, 256); LargeVolume<MaterialDensityPair44> volData(PolyVox::Region::MaxRegion, pager, 256);
//volData.setMaxNumberOfBlocksInMemory(4096); volData.setTargetMemoryUsage(2 * 1024 * 1024); // 2Mb
volData.setMaxNumberOfUncompressedBlocks(64);
//volData.setMaxNumberOfUncompressedBlocks(4096);
//createSphereInVolume(volData, 30); //createSphereInVolume(volData, 30);
//createPerlinTerrain(volData); //createPerlinTerrain(volData);
//createPerlinVolumeSlow(volData); //createPerlinVolumeSlow(volData);

View File

@ -256,7 +256,7 @@ namespace PolyVox
POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const; POLYVOX_DEPRECATED VoxelType getVoxelAt(const Vector3DInt32& v3dPos) const;
/// Sets the number of blocks for which uncompressed data is stored /// Sets the number of blocks for which uncompressed data is stored
void setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks); void setTargetMemoryUsage(uint32_t uTargetMemoryUsageInBytes);
/// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates /// Sets the voxel at the position given by <tt>x,y,z</tt> coordinates
void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate); void setVoxel(int32_t uXPos, int32_t uYPos, int32_t uZPos, VoxelType tValue, WrapMode eWrapMode = WrapModes::Validate);
/// Sets the voxel at the position given by a 3D vector /// Sets the voxel at the position given by a 3D vector

View File

@ -225,22 +225,26 @@ namespace PolyVox
/// \param uMaxNumberOfUncompressedBlocks The number of blocks for which uncompressed data can be cached. /// \param uMaxNumberOfUncompressedBlocks The number of blocks for which uncompressed data can be cached.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
template <typename VoxelType> template <typename VoxelType>
void LargeVolume<VoxelType>::setMaxNumberOfUncompressedBlocks(uint32_t uMaxNumberOfUncompressedBlocks) void LargeVolume<VoxelType>::setTargetMemoryUsage(uint32_t uTargetMemoryUsageInBytes)
{ {
POLYVOX_THROW_IF(!m_pPager, invalid_operation, "You cannot limit the memory usage of the volume because it was created without a pager attached."); POLYVOX_THROW_IF(!m_pPager, invalid_operation, "You cannot limit the memory usage of the volume because it was created without a pager attached.");
//clearBlockCache(); uint32_t uUncompressedBlockSizeInBytes = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
/*if (m_pRecentlyUsedBlocks.size() > uMaxNumberOfBlocksInMemory) m_uMaxNumberOfUncompressedBlocks = uTargetMemoryUsageInBytes / uUncompressedBlockSizeInBytes;
const uint32_t uMinPracticalNoOfBlocks = 4;
POLYVOX_LOG_WARNING_IF(m_uMaxNumberOfUncompressedBlocks < uMinPracticalNoOfBlocks, "The target memory usage is set too low and cannot be adhered to.");
m_uMaxNumberOfUncompressedBlocks = (std::max)(m_uMaxNumberOfUncompressedBlocks, uMinPracticalNoOfBlocks);
if (m_pRecentlyUsedBlocks.size() > m_uMaxNumberOfUncompressedBlocks)
{ {
flushAll(); flushAll();
}*/ }
m_uMaxNumberOfUncompressedBlocks = uMaxNumberOfUncompressedBlocks; POLYVOX_LOG_DEBUG("Target memory usage for volume set to " << uTargetMemoryUsageInBytes << "bytes ("
<< m_uMaxNumberOfUncompressedBlocks << " blocks of " << uUncompressedBlockSizeInBytes << "bytes each).");
uint32_t uUncompressedBlockSizeInBytes = m_uBlockSideLength * m_uBlockSideLength * m_uBlockSideLength * sizeof(VoxelType);
POLYVOX_LOG_DEBUG("The maximum number of uncompresed blocks has been set to " << m_uMaxNumberOfUncompressedBlocks
<< ", which is " << m_uMaxNumberOfUncompressedBlocks * uUncompressedBlockSizeInBytes << " bytes");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -353,11 +357,13 @@ namespace PolyVox
v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower); v3dEnd.setElement(i, regPrefetch.getUpperCorner().getElement(i) >> m_uBlockSideLengthPower);
} }
// Ensure we don't page in more blocks than the volume can hold.
Region region(v3dStart, v3dEnd); Region region(v3dStart, v3dEnd);
uint32_t uNoOfBlocks = static_cast<uint32_t>(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels()); uint32_t uNoOfBlocks = static_cast<uint32_t>(region.getWidthInVoxels() * region.getHeightInVoxels() * region.getDepthInVoxels());
POLYVOX_LOG_WARNING_IF(uNoOfBlocks > m_uMaxNumberOfUncompressedBlocks, "Attempting to prefetch more than the maximum number of blocks."); POLYVOX_LOG_WARNING_IF(uNoOfBlocks > m_uMaxNumberOfUncompressedBlocks, "Attempting to prefetch more than the maximum number of blocks.");
uNoOfBlocks = (std::min)(uNoOfBlocks, m_uMaxNumberOfUncompressedBlocks); uNoOfBlocks = (std::min)(uNoOfBlocks, m_uMaxNumberOfUncompressedBlocks);
// Loops over the specified positions and touch the corresponding blocks.
for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++) for(int32_t x = v3dStart.getX(); x <= v3dEnd.getX(); x++)
{ {
for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++) for(int32_t y = v3dStart.getY(); y <= v3dEnd.getY(); y++)
@ -598,12 +604,16 @@ namespace PolyVox
template <typename VoxelType> template <typename VoxelType>
void LargeVolume<VoxelType>::purgeNullPtrsFromAllBlocks(void) const void LargeVolume<VoxelType>::purgeNullPtrsFromAllBlocks(void) const
{ {
for (auto blockIter = m_pAllBlocks.begin(); blockIter != m_pAllBlocks.end(); blockIter++) for (auto blockIter = m_pAllBlocks.begin(); blockIter != m_pAllBlocks.end();)
{ {
if (blockIter->second.expired()) if (blockIter->second.expired())
{ {
blockIter = m_pAllBlocks.erase(blockIter); blockIter = m_pAllBlocks.erase(blockIter);
} }
else
{
blockIter++;
}
} }
} }

View File

@ -277,8 +277,7 @@ TestVolume::TestVolume()
m_pSimpleVolume = new SimpleVolume<int32_t>(region); m_pSimpleVolume = new SimpleVolume<int32_t>(region);
m_pLargeVolume = new LargeVolume<int32_t>(region, m_pFilePager, 32); m_pLargeVolume = new LargeVolume<int32_t>(region, m_pFilePager, 32);
//m_pLargeVolume->setMaxNumberOfBlocksInMemory(32); m_pLargeVolume->setTargetMemoryUsage(1 * 1024 * 1024);
m_pLargeVolume->setMaxNumberOfUncompressedBlocks(64);
//Fill the volume with some data //Fill the volume with some data
for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++) for(int z = region.getLowerZ(); z <= region.getUpperZ(); z++)