Get GCC to keep SSE register in all function that uses inline asm

I am writing a C program that should do quick math. I use the built-in SSE build instructions to get some SIMD action (using double precision floating point numbers). I am compiling GCC on Linux.

I am in a situation where I need to iterate over some data, and I use a constant coefficient in my calculations. I would like to keep this factor in a safe register during the loop, so I don't need to reload it every time.

To clarify the code:

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;" ); } } 

I tried to do something with the keyword "register". But if I'm not mistaken, it looks like I can save a pointer to this structure (in general case). This will need to be postponed every iteration, wasting precious time.

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

I do not just want to assume that GCC will not change the case of xmm1, it is too many of the "demons flying from one nose" :-). Therefore, I hope that there is a right way to do this.

+7
c assembly gcc inline-assembly sse
source share
3 answers

I think the solution here is for gcc to realize that your type vec2_t is actually a vector; then you can simply compute the value depending on the loop and consider it as a normal variable (except that the compiler knows that it is a vector type):

 typedef double vec2_t __attribute__ ((vector_size (16))); void function() { /* get a specific value set up, eg */ 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 ); } } 

I just compiled this with a simple calculation inside the loop, and at least with optimization level 1, the invariant value is stored in the XMM register during the loop.

(All of this assumes that you do not need your loop invariant in the explicit XMM register and that you can use the distribution of regular GCC registers).

+8
source share

I think it's best to leave the registrar job to the compiler. Perhaps he is better at tracking this than you. GCC will already use SSE extensions, but if you're sure you know better, use the GCC __builtin features. Honestly, I have little doubt that you will do it faster.

Good luck

These sites are probably interesting to see.

GCC X86 Built-in Features

Work with SIMD with GCC

+3
source share

I'm used to working with assembly and C, and what I would do here is that I will write the entire function in the assembly. If you have a flexible make system, I recommend that you configure the ASM function separately and associate it with your application. The only problem is that the function cannot be built into the compiler.

function void (void); // C

external function "C" (void); // C ++

+3
source share

All Articles