Skip to content
Snippets Groups Projects
Commit 72f20a63 authored by Ger van Diepen's avatar Ger van Diepen
Browse files

BugID: 738

Improved default alignment value.
Also improved comments.
parent 6b89f3e1
No related branches found
No related tags found
No related merge requests found
......@@ -156,6 +156,10 @@ namespace LOFAR {
uint getAlignment() const
{ return itsAlignment; }
// Return the greatest power of 2 that divides the value.
// It is used to make the default alignment a power of 2.
static uint p2divider (uint value);
// Helper functions for BlobFieldSet.
// <group>
// Reserve space for this field in an output blob and set its offset.
......@@ -225,8 +229,14 @@ namespace LOFAR {
//
// A field can be a scalar or an array of any dimensionality.
// Care is taken that the field is aligned properly when the blob is created.
// By default a field is aligned on a multiple of its element size
// (e.g. 8 bytes for a double), but it is possible to specify the alignment.
// By default a field is aligned on a multiple of its basic element size
// (e.g. 8 bytes for a double), but it is possible to specify the alignment
// explicitly (which has to be a power of 2). E.g. to be able to use SSE
// instructions an alignment of 16 should be specified explicitly.
// The basic element size is the greatest divider of the element size
// that is a power of 2. E.g. for an array of structs containing 3 floats,
// the element size is 12, but the basic element size is 4.
// For a struct containing 2 floats the basic element size would be 8.
//
// Because a blob can be used to exchange data between different systems,
// it must be possible to convert data as needed (for instance from big to
......@@ -279,6 +289,10 @@ namespace LOFAR {
BlobField (uint version, uint32 size0);
// Define a 2-dim array with axes by default in Fortran order.
// The default alignment is set to the greatest power of 2 that
// divided sizeof(T).
// E.g. for a struct containing 3 floats, the default alignment is 4.
// For a struct containing 2 floats the default alignment is 8.
BlobField (uint version, uint32 size0, uint32 size1,
bool fortranOrder = true);
BlobField (uint version, uint32 size0, uint32 size1, uint32 size2,
......
......@@ -39,14 +39,14 @@ namespace LOFAR {
BlobField<T>::BlobField (uint version)
: BlobFieldBase (version)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
BlobField<T>::BlobField (uint version, uint32 size0)
: BlobFieldBase (version, size0)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......@@ -54,7 +54,7 @@ namespace LOFAR {
bool fortranOrder)
: BlobFieldBase (version, size0, size1, fortranOrder)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......@@ -62,7 +62,7 @@ namespace LOFAR {
uint32 size2, bool fortranOrder)
: BlobFieldBase (version, size0, size1, size2, fortranOrder)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......@@ -70,7 +70,7 @@ namespace LOFAR {
uint32 size2, uint32 size3, bool fortranOrder)
: BlobFieldBase (version, size0, size1, size2, size3, fortranOrder)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......@@ -78,7 +78,7 @@ namespace LOFAR {
bool fortranOrder)
: BlobFieldBase (version, shape, fortranOrder)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......@@ -86,7 +86,7 @@ namespace LOFAR {
bool fortranOrder)
: BlobFieldBase (version, shape, ndim, fortranOrder)
{
setAlignment (sizeof(T));
setAlignment (p2divider(sizeof(T)));
}
template<typename T>
......
......@@ -161,6 +161,20 @@ namespace LOFAR {
}
}
uint BlobFieldBase::p2divider (uint value)
{
if ((value & (value-1)) != 0) {
// No power of 2, so find greatest power of 2 that divides value.
uint v = value;
value = 1;
while (v%2 == 0) {
value *= 2;
v /= 2;
}
}
return value;
}
} // end namespace
......
......@@ -39,7 +39,8 @@ BlobString::BlobString (bool useString, size_t capacity,
{
// Make sure alignment is power of 2.
if (alignment > 1) {
ASSERT ((alignment & (alignment-1)) == 0);
ASSERTSTR ((alignment & (alignment-1)) == 0,
"Blob alignment " << alignment << " must be a power of 2");
}
reserve (capacity);
itsCanIncr = canIncreaseCapacity;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment