Commit 013fed02 authored by BRAMAS Berenger's avatar BRAMAS Berenger

use aligned memory for the blocked tree and the particles container

parent bc73d8e6
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "../Utils/FAssert.hpp" #include "../Utils/FAssert.hpp"
#include "../Containers/FTreeCoordinate.hpp" #include "../Containers/FTreeCoordinate.hpp"
#include "../Utils/FAlignedMemory.hpp"
#include <list> #include <list>
#include <functional> #include <functional>
...@@ -29,6 +30,22 @@ class FGroupOfParticles { ...@@ -29,6 +30,22 @@ class FGroupOfParticles {
}; };
protected: protected:
static const int MemoryAlignementBytes = 32;
static const int MemoryAlignementParticles = MemoryAlignementBytes/sizeof(FReal);
/** This function return the correct number of particles that should be used to have a correct pack.
* If alignement is 32 and use double (so 4 particles in pack), then this function returns:
* RoundToUpperParticles(1) = 1 + 3 = 4
* RoundToUpperParticles(63) = 63 + 1 = 64
*/
template <class NumClass>
static NumClass RoundToUpperParticles(const NumClass& nbParticles){
return nbParticles + (MemoryAlignementParticles - (nbParticles%MemoryAlignementParticles)%MemoryAlignementParticles);
}
//< This value is for not used leaves
static const int LeafIsEmptyFlag = -1;
//< Pointer to a block memory //< Pointer to a block memory
unsigned char* memoryBuffer; unsigned char* memoryBuffer;
...@@ -40,6 +57,8 @@ protected: ...@@ -40,6 +57,8 @@ protected:
LeafHeader* leafHeader; LeafHeader* leafHeader;
//< The total number of particles in the group //< The total number of particles in the group
const int nbParticlesInGroup; const int nbParticlesInGroup;
//< The real number of particles allocated
int nbParticlesAllocatedInGroup;
//< Pointers to particle position x, y, z //< Pointers to particle position x, y, z
FReal* particlePosition[3]; FReal* particlePosition[3];
...@@ -51,9 +70,6 @@ protected: ...@@ -51,9 +70,6 @@ protected:
//< Bytes difference/offset between attributes //< Bytes difference/offset between attributes
size_t attributeOffset; size_t attributeOffset;
//< This value is for not used leaves
static const int LeafIsEmptyFlag = -1;
public: public:
/** /**
* @brief FGroupOfParticles * @brief FGroupOfParticles
...@@ -63,20 +79,24 @@ public: ...@@ -63,20 +79,24 @@ public:
*/ */
FGroupOfParticles(const MortonIndex inStartingIndex, const MortonIndex inEndingIndex, const int inNumberOfLeaves, const int inNbParticles) FGroupOfParticles(const MortonIndex inStartingIndex, const MortonIndex inEndingIndex, const int inNumberOfLeaves, const int inNbParticles)
: memoryBuffer(nullptr), blockHeader(nullptr), blockIndexesTable(nullptr), leafHeader(nullptr), nbParticlesInGroup(inNbParticles), : memoryBuffer(nullptr), blockHeader(nullptr), blockIndexesTable(nullptr), leafHeader(nullptr), nbParticlesInGroup(inNbParticles),
positionOffset(0), attributeOffset(0) { nbParticlesAllocatedInGroup(0), positionOffset(0), attributeOffset(0) {
memset(particlePosition, 0, sizeof(particlePosition)); memset(particlePosition, 0, sizeof(particlePosition));
memset(particleAttributes, 0, sizeof(particleAttributes)); memset(particleAttributes, 0, sizeof(particleAttributes));
nbParticlesAllocatedInGroup = RoundToUpperParticles(nbParticlesInGroup+(MemoryAlignementParticles-1)*inNumberOfLeaves);
// Find the number of leaf to allocate in the blocks // Find the number of leaf to allocate in the blocks
const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex); const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex);
FAssertLF(inNumberOfLeaves <= blockIndexesTableSize); FAssertLF(inNumberOfLeaves <= blockIndexesTableSize);
// Total number of bytes in the block // Total number of bytes in the block
const size_t sizeOfOneParticle = (3*sizeof(FReal) + NbAttributesPerParticle*sizeof(AttributeClass)); const size_t sizeOfOneParticle = (3*sizeof(FReal) + NbAttributesPerParticle*sizeof(AttributeClass));
const size_t memoryToAlloc = sizeof(BlockHeader) + (blockIndexesTableSize*sizeof(int)) + (inNumberOfLeaves*sizeof(LeafHeader)) const size_t memoryToAlloc = sizeof(BlockHeader)
+ inNbParticles*sizeOfOneParticle; + (blockIndexesTableSize*sizeof(int))
+ (inNumberOfLeaves*sizeof(LeafHeader))
+ nbParticlesAllocatedInGroup*sizeOfOneParticle;
// Allocate // Allocate
memoryBuffer = new unsigned char[memoryToAlloc]; memoryBuffer = (unsigned char*)FAlignedMemory::Allocate32BAligned(memoryToAlloc);
FAssertLF(memoryBuffer); FAssertLF(memoryBuffer);
memset(memoryBuffer, 0, memoryToAlloc); memset(memoryBuffer, 0, memoryToAlloc);
...@@ -92,17 +112,18 @@ public: ...@@ -92,17 +112,18 @@ public:
blockHeader->blockIndexesTableSize = blockIndexesTableSize; blockHeader->blockIndexesTableSize = blockIndexesTableSize;
// Init particle pointers // Init particle pointers
positionOffset = (sizeof(FReal) * inNbParticles); positionOffset = (sizeof(FReal) * nbParticlesAllocatedInGroup);
particlePosition[0] = reinterpret_cast<FReal*>(leafHeader + inNumberOfLeaves); particlePosition[0] = reinterpret_cast<FReal*>((reinterpret_cast<size_t>(leafHeader + inNumberOfLeaves)
particlePosition[1] = (particlePosition[0] + inNbParticles); +MemoryAlignementBytes-1) & ~(MemoryAlignementBytes-1));
particlePosition[2] = (particlePosition[1] + inNbParticles); particlePosition[1] = (particlePosition[0] + nbParticlesAllocatedInGroup);
particlePosition[2] = (particlePosition[1] + nbParticlesAllocatedInGroup);
// Redirect pointer to data // Redirect pointer to data
attributeOffset = (sizeof(AttributeClass) * inNbParticles); attributeOffset = (sizeof(AttributeClass) * nbParticlesAllocatedInGroup);
unsigned char* previousPointer = reinterpret_cast<unsigned char*>(particlePosition[2] + inNbParticles); unsigned char* previousPointer = reinterpret_cast<unsigned char*>(particlePosition[2] + nbParticlesAllocatedInGroup);
for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){ for(unsigned idxAttribute = 0 ; idxAttribute < NbAttributesPerParticle ; ++idxAttribute){
particleAttributes[idxAttribute] = reinterpret_cast<AttributeClass*>(previousPointer); particleAttributes[idxAttribute] = reinterpret_cast<AttributeClass*>(previousPointer);
previousPointer += sizeof(AttributeClass)*inNbParticles; previousPointer += sizeof(AttributeClass)*nbParticlesAllocatedInGroup;
} }
// Set all index to not used // Set all index to not used
...@@ -113,7 +134,7 @@ public: ...@@ -113,7 +134,7 @@ public:
/** Call the destructor of leaves and dealloc block memory */ /** Call the destructor of leaves and dealloc block memory */
~FGroupOfParticles(){ ~FGroupOfParticles(){
delete[] memoryBuffer; FAlignedMemory::Dealloc32BAligned(memoryBuffer);
} }
/** The index of the fist leaf (set from the constructor) */ /** The index of the fist leaf (set from the constructor) */
...@@ -152,13 +173,17 @@ public: ...@@ -152,13 +173,17 @@ public:
} }
/** Allocate a new leaf by calling its constructor */ /** Allocate a new leaf by calling its constructor */
void newLeaf(const MortonIndex inIndex, const int id, const int nbParticles, const size_t offsetInGroup){ size_t newLeaf(const MortonIndex inIndex, const int id, const int nbParticles, const size_t offsetInGroup){
FAssertLF(isInside(inIndex)); FAssertLF(isInside(inIndex));
FAssertLF(!exists(inIndex)); FAssertLF(!exists(inIndex));
FAssertLF(id < blockHeader->blockIndexesTableSize); FAssertLF(id < blockHeader->blockIndexesTableSize);
blockIndexesTable[inIndex-blockHeader->startingIndex] = id; blockIndexesTable[inIndex-blockHeader->startingIndex] = id;
leafHeader[id].nbParticles = nbParticles; leafHeader[id].nbParticles = nbParticles;
leafHeader[id].offSet = offsetInGroup; leafHeader[id].offSet = offsetInGroup;
const size_t nextLeafOffsetInGroup = RoundToUpperParticles(offsetInGroup+nbParticles);
FAssertLF(nextLeafOffsetInGroup <= size_t(nbParticlesAllocatedInGroup));
return nextLeafOffsetInGroup;
} }
/** Iterate on each allocated leaves */ /** Iterate on each allocated leaves */
......
...@@ -105,7 +105,7 @@ public: ...@@ -105,7 +105,7 @@ public:
// Initialize each cell of the block // Initialize each cell of the block
int cellIdInBlock = 0; int cellIdInBlock = 0;
int nbParticlesBeforeLeaf = 0; size_t nbParticlesOffsetBeforeLeaf = 0;
while(cellIdInBlock != sizeOfBlock){ while(cellIdInBlock != sizeOfBlock){
// Add cell // Add cell
const CellClass*const oldNode = blockIteratorInOctree.getCurrentCell(); const CellClass*const oldNode = blockIteratorInOctree.getCurrentCell();
...@@ -116,14 +116,13 @@ public: ...@@ -116,14 +116,13 @@ public:
newNode->setCoordinate(oldNode->getCoordinate()); newNode->setCoordinate(oldNode->getCoordinate());
// Add leaf // Add leaf
newParticleBlock->newLeaf(oldNode->getMortonIndex(), cellIdInBlock, nbParticlesOffsetBeforeLeaf = newParticleBlock->newLeaf(oldNode->getMortonIndex(), cellIdInBlock,
blockIteratorInOctree.getCurrentLeaf()->getSrc()->getNbParticles(), blockIteratorInOctree.getCurrentLeaf()->getSrc()->getNbParticles(),
nbParticlesBeforeLeaf); nbParticlesOffsetBeforeLeaf);
BasicAttachedClass attachedLeaf = newParticleBlock->template getLeaf<BasicAttachedClass>(oldNode->getMortonIndex()); BasicAttachedClass attachedLeaf = newParticleBlock->template getLeaf<BasicAttachedClass>(oldNode->getMortonIndex());
attachedLeaf.copyFromContainer(blockIteratorInOctree.getCurrentLeaf()->getSrc(), 0); attachedLeaf.copyFromContainer(blockIteratorInOctree.getCurrentLeaf()->getSrc(), 0);
nbParticlesBeforeLeaf += blockIteratorInOctree.getCurrentLeaf()->getSrc()->getNbParticles();
cellIdInBlock += 1; cellIdInBlock += 1;
blockIteratorInOctree.moveRight(); blockIteratorInOctree.moveRight();
} }
...@@ -260,7 +259,7 @@ public: ...@@ -260,7 +259,7 @@ public:
sizeOfBlock, lastParticle-firstParticle); sizeOfBlock, lastParticle-firstParticle);
// Init cells // Init cells
int nbParticlesBeforeLeaf = 0; size_t nbParticlesOffsetBeforeLeaf = 0;
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){ for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock); newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
...@@ -271,16 +270,14 @@ public: ...@@ -271,16 +270,14 @@ public:
newNode->setCoordinate(coord); newNode->setCoordinate(coord);
// Add leaf // Add leaf
newParticleBlock->newLeaf(currentBlockIndexes[cellIdInBlock], cellIdInBlock, nbParticlesOffsetBeforeLeaf = newParticleBlock->newLeaf(currentBlockIndexes[cellIdInBlock], cellIdInBlock,
nbParticlesPerLeaf[cellIdInBlock], nbParticlesBeforeLeaf); nbParticlesPerLeaf[cellIdInBlock], nbParticlesOffsetBeforeLeaf);
BasicAttachedClass attachedLeaf = newParticleBlock->template getLeaf<BasicAttachedClass>(currentBlockIndexes[cellIdInBlock]); BasicAttachedClass attachedLeaf = newParticleBlock->template getLeaf<BasicAttachedClass>(currentBlockIndexes[cellIdInBlock]);
// Copy each particle from the original position // Copy each particle from the original position
for(int idxPart = 0 ; idxPart < nbParticlesPerLeaf[cellIdInBlock] ; ++idxPart){ for(int idxPart = 0 ; idxPart < nbParticlesPerLeaf[cellIdInBlock] ; ++idxPart){
attachedLeaf.setParticle(idxPart, particlesToSort[idxPart + firstParticle].originalIndex, inParticlesContainer); attachedLeaf.setParticle(idxPart, particlesToSort[idxPart + firstParticle].originalIndex, inParticlesContainer);
} }
nbParticlesBeforeLeaf += nbParticlesPerLeaf[cellIdInBlock];
} }
// Keep the block // Keep the block
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment