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
This commit is contained in:
Kohei Yoshida 2014-02-26 16:29:27 -05:00
parent 6ef6dd0122
commit 03f7a34201
9 changed files with 186 additions and 1 deletions

View File

@ -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;

View File

@ -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 \

View File

@ -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 <sal/saldllapi.h>
#include <sal/types.h>
#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: */

26
sal/osl/unx/memory.c Normal file
View File

@ -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 <internal/oslmemory.h>
#include <stdlib.h>
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: */

24
sal/osl/w32/memory.c Normal file
View File

@ -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 <internal/oslmemory.h>
#include <malloc.h>
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: */

View File

@ -27,6 +27,7 @@
#include <stdio.h>
#include "internal/rtllifecycle.h"
#include <internal/oslmemory.h>
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: */

View File

@ -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;

View File

@ -13,6 +13,7 @@
#include "address.hxx"
#include "types.hxx"
#include "platforminfo.hxx"
#include <stlalgorithm.hxx>
#include "svl/sharedstringpool.hxx"
@ -28,7 +29,8 @@ namespace sc {
struct FormulaGroupContext : boost::noncopyable
{
typedef std::vector<double> NumArrayType;
typedef AlignedAllocator<double,256> DoubleAllocType;
typedef std::vector<double, DoubleAllocType> NumArrayType;
typedef std::vector<rtl_uString*> StrArrayType;
typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;

View File

@ -11,6 +11,9 @@
#define __SC_STLALGORITHM_HXX__
#include <functional>
#include <limits>
#include <rtl/alloc.h>
/**
* Function object to allow deleting instances stored in STL containers as
@ -25,6 +28,63 @@ struct ScDeleteObjectByPtr : public ::std::unary_function<T*, void>
}
};
namespace sc {
/**
* Custom allocator for STL container to ensure that the base address of
* allocated storage is aligned to a specified boundary.
*/
template<typename T, size_t _Alignment>
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<typename _Type2>
struct rebind
{
typedef AlignedAllocator<_Type2,_Alignment> other;
};
AlignedAllocator() {}
~AlignedAllocator() {}
template<typename _Type2>
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<size_type>::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: */