aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2009-06-22 10:44:09 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2009-06-22 10:44:09 +0200
commitec8596f86356d411a49b204594aae2d002eb8770 (patch)
treeaccb98dad0a8d8107759f19748c0157f2b9bb61e /doc
parentac9680fb20436f2a545ecc104398838bf397c645 (diff)
update the stack alignment doc
Diffstat (limited to 'doc')
-rw-r--r--doc/D03_WrongStackAlignment.dox24
1 files changed, 17 insertions, 7 deletions
diff --git a/doc/D03_WrongStackAlignment.dox b/doc/D03_WrongStackAlignment.dox
index e49168066..09711af9c 100644
--- a/doc/D03_WrongStackAlignment.dox
+++ b/doc/D03_WrongStackAlignment.dox
@@ -16,9 +16,12 @@ void foo()
GCC assumes that the stack is already 16-byte-aligned so that the object \a q will be created at a 16-byte-aligned location. For this reason, it doesn't take any special care to explicitly align the object \a q, as Eigen requires.
-The problem is that this assumption is wrong on Windows, where the stack is not guaranteed to have 16-byte alignment. This results in the object 'q' being created at an unaligned location, making your program crash with the \ref UnalignedArrayAssert "assertion on unaligned arrays".
+The problem is that, in some particular cases, this assumption can be wrong on Windows, where the stack is only guaranteed to have 4-byte alignment. Indeed, even though GCC takes care of aligning the stack in the main function and does its best to keep it aligned, when a function is called from another thread or from a binary compiled with another compiler, the stack alignment can be corrupted. This results in the object 'q' being created at an unaligned location, making your program crash with the \ref UnalignedArrayAssert "assertion on unaligned arrays". So far we found the three following solutions.
-A local solution is to mark your function with this attribute:
+
+\section sec_sol1 Local solution
+
+A local solution is to mark such a function with this attribute:
\code
__attribute__((force_align_arg_pointer)) void foo()
{
@@ -26,17 +29,24 @@ __attribute__((force_align_arg_pointer)) void foo()
//...
}
\endcode
-Read <a href="http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Function-Attributes.html#Function-Attributes">this GCC documentation</a> to understand what this does. Of course this should only be done on GCC on Windows, so for portability you'll have to encapsulate this in a macro which you leave empty on other platforms. Also this needs to be done for every such function, which is inconvenient! So you may prefer the following global solution:
+Read <a href="http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Function-Attributes.html#Function-Attributes">this GCC documentation</a> to understand what this does. Of course this should only be done on GCC on Windows, so for portability you'll have to encapsulate this in a macro which you leave empty on other platforms. The advantage of this solution is that you can finely select which function might have a corrupted stack alignment. Of course on the downside this has to be done for every such function, so you may prefer one of the following two global solutions.
+
+
+\section sec_sol2 Global solutions
A global solution is to edit your project so that when compiling with GCC on Windows, you pass this option to GCC:
\code
--mpreferred-stack-boundary=3
+-mincoming-stack-boundary=2
\endcode
-or
+Explanation: this tells GCC that the stack is only required to be aligned to 2^2=4 bytes, so that GCC now knows that it really must take extra care to honor the 16 byte alignment of \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types" when needed.
+
+Another global solution is to pass this option to gcc:
\code
--mpreferred-stack-boundary=2
+-mstackrealign
\endcode
-Explanation: this tells GCC that the stack should only be required to be aligned to 2^3=8 byes (in the first version) or to 2^2=4 bytes (in the second version). In both cases, this is smaller than 16 bytes, so GCC now knows that it really must take extra care to honor the 16 byte alignment of \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types". However, you must make sure that you understand fully what this does, before applying this change to your project. Read the GCC manual page. A too low value of \c -mpreferred-stack-boundary can result in poor performance: for example, on various CPUs, double-precision numbers work much faster when aligned to 8 bytes boundary, which is guaranteed by \c -mpreferred-stack-boundary=3 but not by \c -mpreferred-stack-boundary=2, so passing \c -mpreferred-stack-boundary=2 can result in poor performance! On the other hand, notice that the higher the value of \c -mpreferred-stack-boundary, the bigger the code size.
+which has the same effect than adding the \c force_align_arg_pointer attribute to all functions.
+
+These global solutions are easy to use, but note that they may slowdown your program because they lead to extra prologue/epilogue instructions for every function.
*/