1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0024405: TKernel - add aligned allocator class Standard_MMgrAligned

New class NCollection_AlignedAllocator.
New macros STANDARD_ALIGNED.
New methods Standard::AllocateAligned() and Standard::FreeAligned().
Add missing Standard_EXPORT
This commit is contained in:
kgv 2014-04-03 16:31:35 +04:00 committed by apn
parent ad3217cd8d
commit acc625609d
7 changed files with 184 additions and 42 deletions

View File

@ -14,43 +14,7 @@
// commercial license or contractual agreement.
#include <Image_PixMap.hxx>
#ifdef _MSC_VER
#include <malloc.h>
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
#include <mm_malloc.h>
#else
extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theBytesCount);
#endif
template<typename TypePtr>
inline TypePtr MemAllocAligned (const Standard_Size& theBytesCount,
const Standard_Size& theAlign = 16)
{
#if defined(_MSC_VER)
return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
return (TypePtr ) _mm_malloc (theBytesCount, theAlign);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theBytesCount))
{
aPtr = NULL;
}
return (TypePtr )aPtr;
#endif
}
inline void MemFreeAligned (void* thePtrAligned)
{
#if defined(_MSC_VER)
_aligned_free (thePtrAligned);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
_mm_free (thePtrAligned);
#else
free (thePtrAligned);
#endif
}
#include <Standard.hxx>
IMPLEMENT_STANDARD_HANDLE (Image_PixMap, Standard_Transient)
IMPLEMENT_STANDARD_RTTIEXT(Image_PixMap, Standard_Transient)
@ -171,7 +135,7 @@ bool Image_PixMap::InitTrash (Image_PixMap::ImgFormat thePixelFormat,
// use argument only if it greater
myData.mySizeRowBytes = theSizeRowBytes;
}
myData.myDataPtr = MemAllocAligned<Standard_Byte*> (SizeBytes());
myData.myDataPtr = (Standard_Byte* )Standard::AllocateAligned (SizeBytes(), 16);
myIsOwnPointer = true;
setTopDown();
return myData.myDataPtr != NULL;
@ -222,7 +186,7 @@ void Image_PixMap::Clear (Image_PixMap::ImgFormat thePixelFormat)
{
if (myIsOwnPointer && (myData.myDataPtr != NULL))
{
MemFreeAligned (myData.myDataPtr);
Standard::FreeAligned (myData.myDataPtr);
}
myData.myDataPtr = myData.myTopRowPtr = NULL;
myIsOwnPointer = true;

View File

@ -4,6 +4,8 @@ NCollection_BaseAllocator.hxx
NCollection_BaseAllocator.cxx
NCollection_IncAllocator.hxx
NCollection_IncAllocator.cxx
NCollection_AlignedAllocator.hxx
NCollection_AlignedAllocator.cxx
NCollection_HeapAllocator.hxx
NCollection_HeapAllocator.cxx
NCollection_StdAllocator.hxx

View File

@ -0,0 +1,47 @@
// Created on: 2014-03-31
// Created by: Kirill Gavrilov
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <NCollection_AlignedAllocator.hxx>
IMPLEMENT_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator)
IMPLEMENT_STANDARD_RTTIEXT (NCollection_AlignedAllocator, NCollection_BaseAllocator)
//=======================================================================
//function : NCollection_AlignedAllocator()
//purpose : Constructor
//=======================================================================
NCollection_AlignedAllocator::NCollection_AlignedAllocator (const size_t theAlignment)
: myAlignment (theAlignment)
{
//
}
//=======================================================================
//function : Allocate
//purpose : allocate a memory
//=======================================================================
void* NCollection_AlignedAllocator::Allocate (const size_t theSize)
{
return Standard::AllocateAligned (theSize, myAlignment);
}
//=======================================================================
//function : Free
//purpose :
//=======================================================================
void NCollection_AlignedAllocator::Free (void* thePtr)
{
Standard::FreeAligned (thePtr);
}

View File

@ -0,0 +1,56 @@
// Created on: 2014-03-31
// Created by: Kirill Gavrilov
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef NCollection_AlignedAllocator_HeaderFile
#define NCollection_AlignedAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#include <Standard.hxx>
//! NCollection allocator with managed memory alignment capabilities.
class NCollection_AlignedAllocator : public NCollection_BaseAllocator
{
public:
//! Constructor. The alignment should be specified explicitly:
//! 16 bytes for SSE instructions
//! 32 bytes for AVX instructions
Standard_EXPORT NCollection_AlignedAllocator (const size_t theAlignment);
//! Allocate memory with given size. Returns NULL on failure.
Standard_EXPORT virtual void* Allocate (const size_t theSize);
//! Free a previously allocated memory.
Standard_EXPORT virtual void Free (void* thePtr);
private:
NCollection_AlignedAllocator (const NCollection_AlignedAllocator& );
NCollection_AlignedAllocator& operator= (const NCollection_AlignedAllocator& );
protected:
size_t myAlignment; //!< alignment in bytes
public:
DEFINE_STANDARD_RTTI (NCollection_AlignedAllocator)
};
// Definition of HANDLE object using Standard_DefineHandle.hxx
DEFINE_STANDARD_HANDLE (NCollection_AlignedAllocator, NCollection_BaseAllocator)
#endif // NCollection_AlignedAllocator_HeaderFile

View File

@ -146,6 +146,20 @@ is
-- aStorage - previously allocated memory block
-- aNewSize - new size in bytes
AllocateAligned (theSize : Size from Standard;
theAlign : Size from Standard)
returns Address from Standard;
---Purpose: Allocates aligned memory blocks.
-- Should be used with CPU instructions which require specific alignment.
-- For example: SSE requires 16 bytes, AVX requires 32 bytes.
-- @param theSize bytes to allocate
-- @param theAlign alignment in bytes
FreeAligned (thePtrAligned : Address from Standard);
---Purpose: Deallocates memory blocks
-- @param thePtrAligned the memory block previously allocated with AllocateAligned()
---C++: alias "template <typename T> static inline void FreeAligned (T*& thePtrAligned) { FreeAligned ((void* )thePtrAligned); thePtrAligned = 0; }"
Purge returns Integer from Standard;
---Purpose: Deallocates the storage retained on the free list
-- and clears the list.

View File

@ -28,6 +28,14 @@
#include <locale.h>
#endif
#ifdef _MSC_VER
#include <malloc.h>
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
#include <mm_malloc.h>
#else
extern "C" int posix_memalign (void** thePtr, size_t theAlign, size_t theSize);
#endif
#ifndef OCCT_MMGT_OPT_DEFAULT
#define OCCT_MMGT_OPT_DEFAULT 0
#endif
@ -183,7 +191,7 @@ Standard_Address Standard::Allocate(const Standard_Size size)
}
//=======================================================================
//function : FreeAddress
//function : Free
//purpose :
//=======================================================================
@ -212,3 +220,41 @@ Standard_Integer Standard::Purge()
{
return GetMMgr()->Purge();
}
//=======================================================================
//function : AllocateAligned
//purpose :
//=======================================================================
Standard_Address Standard::AllocateAligned (const Standard_Size theSize,
const Standard_Size theAlign)
{
#if defined(_MSC_VER)
return _aligned_malloc (theSize, theAlign);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
return _mm_malloc (theSize, theAlign);
#else
void* aPtr;
if (posix_memalign (&aPtr, theAlign, theSize))
{
return NULL;
}
return aPtr;
#endif
}
//=======================================================================
//function : FreeAligned
//purpose :
//=======================================================================
void Standard::FreeAligned (Standard_Address thePtrAligned)
{
#if defined(_MSC_VER)
_aligned_free (thePtrAligned);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
_mm_free (thePtrAligned);
#else
free (thePtrAligned);
#endif
}

View File

@ -14,7 +14,7 @@
// commercial license or contractual agreement.
#ifndef _Standard_DefineAlloc_HeaderFile
# define _Standard_DefineAlloc_HeaderFile
#define _Standard_DefineAlloc_HeaderFile
// Macro to override new and delete operators for arrays.
// Defined to empty for old SUN compiler
@ -76,4 +76,17 @@ inline void* operator new(size_t,void* anAddress)
#endif
#endif
//! @def STANDARD_ALIGNED(theAlignment, theType, theVar)
//! Declare variable with memory alignment.
//! @code
//! static const STANDARD_ALIGNED(8, char, THE_ARRAY)[] = {0xFF, 0xFE, 0xFA, 0xFB, 0xFF, 0x11, 0x22, 0x33};
//! @endcode
#if defined(_MSC_VER)
#define STANDARD_ALIGNED(theAlignment, theType, theVar) __declspec(align(theAlignment)) theType theVar
#elif defined(__GNUC__)
#define STANDARD_ALIGNED(theAlignment, theType, theVar) theType __attribute__ ((aligned (theAlignment))) theVar
#else
#define STANDARD_ALIGNED(theAlignment, theType, theVar) theType theVar
#endif
#endif // _Standard_DefineAlloc_HeaderFile