From 03f7a342011a4f69cfcbec7af3e4f1a2e835618b Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Wed, 26 Feb 2014 16:29:27 -0500 Subject: [PATCH] Ensure that numeric array storage is aligned to 256-byte boundary. OpenCL devices require this else we would get a performance hit. Change-Id: I6b1db6320fa84f933b6446022a0fd02ba267bf21 --- include/rtl/alloc.h | 24 +++++++++++++++ sal/Library_sal.mk | 2 ++ sal/inc/internal/oslmemory.h | 30 ++++++++++++++++++ sal/osl/unx/memory.c | 26 ++++++++++++++++ sal/osl/w32/memory.c | 24 +++++++++++++++ sal/rtl/alloc_global.cxx | 11 +++++++ sal/util/sal.map | 6 ++++ sc/inc/formulagroup.hxx | 4 ++- sc/inc/stlalgorithm.hxx | 60 ++++++++++++++++++++++++++++++++++++ 9 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 sal/inc/internal/oslmemory.h create mode 100644 sal/osl/unx/memory.c create mode 100644 sal/osl/w32/memory.c diff --git a/include/rtl/alloc.h b/include/rtl/alloc.h index 9d0b44e862b1..f3459bac3e42 100644 --- a/include/rtl/alloc.h +++ b/include/rtl/alloc.h @@ -96,6 +96,30 @@ SAL_DLLPUBLIC void SAL_CALL rtl_freeZeroMemory ( ) SAL_THROW_EXTERN_C(); +/** Allocate memory. + + A call to this function will return NULL upon the requested + memory size being either zero or larger than currently allocatable. + + @param Alignment alignment in bytes. + @param Bytes [in] memory size. + @return pointer to allocated memory. + */ +SAL_DLLPUBLIC void* SAL_CALL rtl_allocateAlinedMemory ( + sal_Size Alignment, + sal_Size Bytes +) SAL_THROW_EXTERN_C(); + + +/** Free memory allocated with rtl_allocateAlinedMemory. + @param Ptr [in] pointer to previously allocated memory. + @return none. Memory is released. Ptr is invalid. + */ +SAL_DLLPUBLIC void SAL_CALL rtl_freeAlignedMemory ( + void * Ptr +) SAL_THROW_EXTERN_C(); + + /** Opaque rtl_arena_type. */ typedef struct rtl_arena_st rtl_arena_type; diff --git a/sal/Library_sal.mk b/sal/Library_sal.mk index cbc52a7212bf..6b16426a29ac 100644 --- a/sal/Library_sal.mk +++ b/sal/Library_sal.mk @@ -168,6 +168,7 @@ $(eval $(call gb_Library_add_exception_objects,sal,\ $(if $(filter DESKTOP,$(BUILD_TYPE)), sal/osl/unx/salinit) \ )) $(eval $(call gb_Library_add_cobjects,sal,\ + sal/osl/unx/memory \ sal/osl/unx/mutex \ sal/osl/unx/nlsupport \ sal/osl/unx/pipe \ @@ -253,6 +254,7 @@ $(eval $(call gb_Library_add_cobjects,sal,\ sal/osl/w32/dllentry \ sal/osl/w32/file_error \ sal/osl/w32/interlck \ + sal/osl/w32/memory \ sal/osl/w32/mutex \ sal/osl/w32/nlsupport \ sal/osl/w32/pipe \ diff --git a/sal/inc/internal/oslmemory.h b/sal/inc/internal/oslmemory.h new file mode 100644 index 000000000000..8ef094ad3cad --- /dev/null +++ b/sal/inc/internal/oslmemory.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SAL_INTERNAL_OSLMEMORY_H +#define INCLUDED_SAL_INTERNAL_OSLMEMORY_H + +#include +#include + +#if defined __cplusplus +extern "C" { +#endif + +void* osl_aligned_alloc( sal_Size align, sal_Size size ); + +void osl_aligned_free( void* p ); + +#if defined __cplusplus +} +#endif + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/unx/memory.c b/sal/osl/unx/memory.c new file mode 100644 index 000000000000..a70bc164f0e5 --- /dev/null +++ b/sal/osl/unx/memory.c @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include + +void* osl_aligned_alloc( sal_Size align, sal_Size size ) +{ + void* ptr; + int err = posix_memalign(&ptr, align, size); + return err ? NULL : ptr; +} + +void osl_aligned_free( void* p ) +{ + free(p); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/osl/w32/memory.c b/sal/osl/w32/memory.c new file mode 100644 index 000000000000..279a1681d4e1 --- /dev/null +++ b/sal/osl/w32/memory.c @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include + +void* osl_aligned_alloc( sal_Size align, sal_Size size ) +{ + return _aligned_malloc(size, align); +} + +void osl_aligned_free( void* p ) +{ + _aligned_free(p); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/rtl/alloc_global.cxx b/sal/rtl/alloc_global.cxx index 07cded3eb187..4108333f1fe6 100644 --- a/sal/rtl/alloc_global.cxx +++ b/sal/rtl/alloc_global.cxx @@ -27,6 +27,7 @@ #include #include "internal/rtllifecycle.h" +#include AllocMode alloc_mode = AMode_UNSET; @@ -378,6 +379,16 @@ void SAL_CALL rtl_freeZeroMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C() } } +void* SAL_CALL rtl_allocateAlinedMemory (sal_Size Alignment, sal_Size Bytes) SAL_THROW_EXTERN_C() +{ + return osl_aligned_alloc(Alignment, Bytes); +} + +void SAL_CALL rtl_freeAlignedMemory (void* Ptr) SAL_THROW_EXTERN_C() +{ + osl_aligned_free(Ptr); +} + /* ================================================================= */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sal/util/sal.map b/sal/util/sal.map index 1456d6db1cf8..f63f38b0d0ae 100644 --- a/sal/util/sal.map +++ b/sal/util/sal.map @@ -670,6 +670,12 @@ LIBO_UDK_4.2 { # symbols available in >= LibO 4.2 rtl_ustr_toUInt32; } LIBO_UDK_4.1; +LIBO_UDK_4.3 { # symbols available in >= LibO 4.3 + global: + rtl_allocateAlinedMemory; + rtl_freeAlignedMemory; +} LIBO_UDK_4.2; + PRIVATE_1.0 { global: osl_detail_ObjectRegistry_storeAddresses; diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx index 3834e49bd9d2..602c4a4f6cd1 100644 --- a/sc/inc/formulagroup.hxx +++ b/sc/inc/formulagroup.hxx @@ -13,6 +13,7 @@ #include "address.hxx" #include "types.hxx" #include "platforminfo.hxx" +#include #include "svl/sharedstringpool.hxx" @@ -28,7 +29,8 @@ namespace sc { struct FormulaGroupContext : boost::noncopyable { - typedef std::vector NumArrayType; + typedef AlignedAllocator DoubleAllocType; + typedef std::vector NumArrayType; typedef std::vector StrArrayType; typedef boost::ptr_vector NumArrayStoreType; typedef boost::ptr_vector StrArrayStoreType; diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx index fb5509f50f9c..37d7ba85066a 100644 --- a/sc/inc/stlalgorithm.hxx +++ b/sc/inc/stlalgorithm.hxx @@ -11,6 +11,9 @@ #define __SC_STLALGORITHM_HXX__ #include +#include + +#include /** * Function object to allow deleting instances stored in STL containers as @@ -25,6 +28,63 @@ struct ScDeleteObjectByPtr : public ::std::unary_function } }; +namespace sc { + +/** + * Custom allocator for STL container to ensure that the base address of + * allocated storage is aligned to a specified boundary. + */ +template +class AlignedAllocator +{ +public: + typedef T value_type; + typedef size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef T* pointer; + typedef const T* const_pointer; + typedef T* void_pointer; + + typedef T& reference; + typedef const T& const_reference; + + template + struct rebind + { + typedef AlignedAllocator<_Type2,_Alignment> other; + }; + + AlignedAllocator() {} + ~AlignedAllocator() {} + + template + AlignedAllocator(const AlignedAllocator<_Type2,_Alignment>&) {} + + void construct(T* p, const value_type& val) { new(p) value_type(val); } + void destroy(T* p) { p->~value_type(); } + + size_type max_size() const + { + return std::numeric_limits::max() / sizeof(value_type); + } + + bool operator== (const AlignedAllocator&) const { return true; } + bool operator!= (const AlignedAllocator&) const { return false; } + + pointer allocate(size_type n) + { + return (pointer)rtl_allocateAlinedMemory(_Alignment, n*sizeof(value_type)); + } + + void deallocate(pointer p, size_type) + { + rtl_freeAlignedMemory(p); + } +}; + +} + #endif /* vim:set shiftwidth=4 softtabstop=4 expandtab: */