summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-02-26 16:29:27 -0500
committerJan Holesovsky <kendy@collabora.com>2014-02-28 17:16:42 +0100
commit7da51df558c1fbc21188a0c58773ba549195ca5a (patch)
treef8fc7f0a70cbd6fff709b6e6eb0b3e9790b6a8a6
parentda443ab58158d2b7ffa52742cec2be76e3aa2026 (diff)
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
-rw-r--r--sc/inc/formulagroup.hxx3
-rw-r--r--sc/inc/stlalgorithm.hxx91
2 files changed, 93 insertions, 1 deletions
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 3834e49bd9d2..028a04d82961 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 <stlalgorithm.hxx>
#include "svl/sharedstringpool.hxx"
@@ -28,7 +29,7 @@ namespace sc {
struct FormulaGroupContext : boost::noncopyable
{
- typedef std::vector<double> NumArrayType;
+ typedef std::vector<double, AlignedAllocator<double,256> > NumArrayType;
typedef std::vector<rtl_uString*> StrArrayType;
typedef boost::ptr_vector<NumArrayType> NumArrayStoreType;
typedef boost::ptr_vector<StrArrayType> StrArrayStoreType;
diff --git a/sc/inc/stlalgorithm.hxx b/sc/inc/stlalgorithm.hxx
index fb5509f50f9c..be45e15e86fe 100644
--- a/sc/inc/stlalgorithm.hxx
+++ b/sc/inc/stlalgorithm.hxx
@@ -25,6 +25,97 @@ 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, std::size_t N>
+class AlignedAllocator
+{
+public:
+ typedef T value_type;
+ typedef std::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;
+
+public:
+ AlignedAllocator() throw() {}
+
+ template<typename T2>
+ AlignedAllocator(const AlignedAllocator<T2, N>&) throw() {}
+
+ ~AlignedAllocator() throw() {}
+
+ pointer adress(reference r)
+ {
+ return &r;
+ }
+
+ const_pointer adress(const_reference r) const
+ {
+ return &r;
+ }
+
+ pointer allocate(size_type n)
+ {
+#ifdef WNT
+ return (pointer)_aligned_malloc(n * sizeof(value_type), N);
+#else
+ return (pointer)aligned_alloc(N, n * sizeof(value_type));
+#endif
+ }
+
+ void deallocate(pointer p, size_type)
+ {
+#ifdef WNT
+ _aligned_free(p);
+#else
+ free(p);
+#endif
+ }
+
+ void construct(pointer p, const value_type& wert)
+ {
+ new(p) value_type(wert);
+ }
+
+ void destroy(pointer p)
+ {
+ p->~value_type();
+ }
+
+ size_type max_size() const throw()
+ {
+ return size_type(-1) / sizeof(value_type);
+ }
+
+ template<typename T2>
+ struct rebind
+ {
+ typedef AlignedAllocator<T2, N> other;
+ };
+
+ bool operator==(const AlignedAllocator<T, N>& other) const
+ {
+ return true;
+ }
+
+ bool operator!=(const AlignedAllocator<T, N>& other) const
+ {
+ return !(*this == other);
+ }
+};
+
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */