psi*_*lia 7 c stack gcc sse pthreads
我尝试构建一个使用pthreads和__m128 SSE类型的应用程序.根据GCC手册,默认堆栈对齐是16个字节.为了使用__m128,要求是16字节对齐.
我的目标CPU支持SSE.我使用的GCC编译器不支持运行时堆栈重组(例如-mstackrealign).我不能使用任何其他GCC编译器版本.
我的测试应用程序如下:
#include <xmmintrin.h>
#include <pthread.h>
void *f(void *x){
__m128 y;
...
}
int main(void){
pthread_t p;
pthread_create(&p, NULL, f, NULL);
}
Run Code Online (Sandbox Code Playgroud)
应用程序生成异常并退出.经过简单的调试(printf"%p",&y)后,我发现变量y不是16字节对齐的.
我的问题是:如何在不使用任何GCC标志和属性(它们没有帮助)的情况下正确地重新对齐堆栈(16字节)?我应该在这个线程函数f()中使用GCC内联汇编程序吗?
在堆栈上分配一个大于15字节的数组sizeof(__m128)
,并使用该数组中的第一个对齐地址.如果需要多个,请在具有单个15字节边距的数组中分配它们以进行对齐.
我不记得分配一个unsigned char
数组是否可以使你免受编译器的严格别名优化或者它只能反过来使用.
#include <stdint.h>
void *f(void *x)
{
unsigned char y[sizeof(__m128)+15];
__m128 *py = (__m128*) (((uintptr_t)&y) + 15) & ~(uintptr_t)15);
...
}
Run Code Online (Sandbox Code Playgroud)
psi*_*lia -1
我已经解决了这个问题。这是我的解决方案:
void another_function(){
__m128 y;
...
}
void *f(void *x){
asm("pushl %esp");
asm("subl $16,%esp");
asm("andl $-0x10,%esp");
another_function();
asm("popl %esp");
}
Run Code Online (Sandbox Code Playgroud)
首先,我们将堆栈增加 16 个字节。其次,我们使最低有效半字节等于 0x0。我们使用压入/弹出操作数保留堆栈指针。我们调用另一个函数,它的所有局部变量都是 16 字节对齐的。所有嵌套函数的局部变量也将按 16 字节对齐。
它有效!
归档时间: |
|
查看次数: |
4102 次 |
最近记录: |