我正在写在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;"
        );
    }
}

我一直试图做的“注册”关键字的东西。但是,如果我没有记错,它看起来好像我只能保持一个的指针的该结构(通用寄存器)。这将需要deferenced每次迭代,浪费宝贵的时间。

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 */

我不只是想假设GCC不会改变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
       );
   }
}

我刚编译这个了环内一个简单的计算,和与至少优化级别1 invariant的值的循环期间被保持在XMM寄存器。

(这一切都假定你不这样做的需要的你的循环不变的明确XMM寄存器;并且,您可以使用GCC的正常寄存器分配)。

其他提示

我认为这是最好的离开登记分配到编译器。它也许可以更好地跟踪它比你。 GCC将已经使用SSE扩展指令,但如果你一定要知道更好,使用GCC __builtin功能。 说实话,我怀疑一点点,你会让它更快的方式。

祝您好运!

这些网站可能是有趣的可以关注一下。

GCC X86内置函数

与SIMD

工作与GCC

我使用汇编语言和C和我会在这里做的是,我会写在装配全功能工作。 如果你有一个灵活的使系统,我建议单独组装ASM功能,并将其链接到您的应用程序。与此唯一的问题是,该函数不能被编译器内联。

void函数(无效); // C

外部的 “C” 函数(无效); // C ++

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top