Roa*_*Fre 7 c assembly gcc sse inline-assembly
我正在用C语言编写一个需要进行快速数学计算的程序.我正在使用内联SSE汇编指令来获取一些SIMD操作(使用压缩的双精度浮点数).我在Linux上使用GCC进行编译.
我处在需要循环某些数据的情况下,我在计算中使用了一个常数因子.我想在循环期间将这个因素隐藏在一个安全的寄存器中,所以我不必每次都重新加载它.
用一些代码澄清:
struct vect2 {
fltpt x;
fltpt y;
}__attribute__((aligned(16))); /* Align on 16B boundary for SSE2 instructions */
typedef struct vect2 vect2_t;
void function()
{
/* get a specific value set up in xmm1, and keep it there for the
* rest of the loop. */
for( int i = 0, i<N; i++ ){
asm(
"Some calculations;"
"on an element of;"
"a data set.;"
"The value in xmm1;"
"is needed;"
);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过使用"register"关键字做一些事情.但是,如果我没有弄错,看起来我只能保留指向该结构的指针(在通用寄存器中).这需要每次迭代都要尊重,浪费宝贵的时间.
register vect2_t hVect asm("xmm1") = {h, h};
/* Gives error: data type of 'hVect' isn't suitable for a register */
register vect2_t *hVect2 asm("rax");
*hVect2 = (vect2_t){h,h};
/* Seems to work, but not what I'm looking for */
Run Code Online (Sandbox Code Playgroud)
我不只是假设海湾合作委员会不会改变xmm1登记册,这太过于"从一个人的鼻子里冒出来的恶魔"这样的事情:-).所以我希望有一个正确的方法来做到这一点.
我认为这里的解决方案是让gcc意识到你的vec2_t类型实际上是一个向量; 然后你可以计算循环不变量值并将其视为普通变量(除了编译器知道它是矢量类型):
typedef double vec2_t __attribute__ ((vector_size (16)));
void function()
{
/* get a specific value set up, e.g. */
vec2_t invariant;
asm( "some calculations, soring result in invariant."
: "=x" (invariant) );
for( int i = 0; i<N; i++ ){
asm(
"Some calculations;"
"on an element of;"
"a data set.;"
"The value in xmm1;"
"is needed;"
: "x" (invariant) // and other SSE arguments
);
}
}
Run Code Online (Sandbox Code Playgroud)
我只是通过循环内部的简单计算来编译它,并且至少在优化级别1中,invariant在循环期间将值保存在XMM寄存器中.
(这一切都假定你没有需要你的循环不变的明确XMM寄存器;并且,您可以使用GCC的正常寄存器分配).