Help: Inline assembly (SSE) slowdown

Main Question or Discussion Point

I'm writing a program in C++ in MS Visual Studio.NET, and I am using inline assembly to do some SSE instructions.

The trouble is that I am having a hard time getting the assembly to accep the addresses from my C++ from anyting other than explicitly-declared pointers (not even arrays work!). I end up putting extra variables on the stack so I can get pointers to my data, and I believe that this is causing a performance penalty (CPU time).

My code is this:
Code:
	inline Vector3 operator +(Vector3 &v) const {
		float result[4];
		Vector3 *vout = (Vector3 *)result;
		Vector3 *vin = &v;
		_asm {
			mov esi, vin;
			mov edi, vout;
			mov eax, this;
			movups xmm0, [eax];
			movups xmm1, [esi];
			addps xmm0, xmm1;
			movups [edi], xmm0;
		}
		return *(Vector3 *)result;
	}
Is there any way that I can get the inline assembly to use the needed addresses without the extra Vector3 pointer variables? (And if you have any other optimization suggestions, I'll be glad to hear them. :biggrin: )
 

Answers and Replies

dduardo
Staff Emeritus
1,894
3
GCC has a compiler option for optimizing for SSE. Perhaps VS.NET has the same thing.

The base address of the floating point array should be loaded into a 32 bit register like eax. Move array[0] to sse memory:

movups xmm0, [eax];

To move array[1] into sse memory you would do something like this:

movups xmm1,[eax+0x10];

The 0x10 is the byte offset in hex. This value depends on how many bytes an array value takes up. You can find out by using the sizeof function.

If you don't want the temp variable you need to do something like this:

mov eax, v->array;

You need the base address of the floating point array, not the base address of the Vector3 structure variable.
 
chroot
Staff Emeritus
Science Advisor
Gold Member
10,165
34
Are you actually looking at the compiled output? Or just guessing there's a performance penalty? Honestly, I strongly doubt that pushing one address on the stack is a big deal compared to the SSE instructions themselves. You don't really need to move the addresses into registers, either, I don't think. Turn on optimizations and check the compiler's output.

- Warren
 
dduardo
Staff Emeritus
1,894
3
I would definitely turn on sse optimizations and check the asm produced by the compiler to see if it is actually using sse instructions.

I do believe you need to put the address in a cpu register. You can't just do:

movups xmm0,[v];

And you couldn't do the following because the compiler doesn't know the value of v at compile time.

movups xmm0, *v;
 
Last edited:
jim mcnamara
Mentor
3,652
1,888
Normally, to check performance, you get it working totally correctly. First.
Then worry about optimizations.

Next. If and only if it's running too slowly: To validate/ignore your optimization fears try using a profiler. I dunno if MS provides one for the NET environment or not.

There is nothing worse than misguided optimization to obfuscate and break code.
 
dduardo said:
I do believe you need to put the address in a cpu register. You can't just do:

movups xmm0,[v];
That is correct, I got errors when I tried it without putting it in a register first.

I read something somewhere that you could use the address of your C/C++ variable in the assembly by putting an underscore before the C/C++ variable name, but this doesn't work in VS.NET (It tells me that it's an undeclared symbol). Is there any way you know of to tell the assembly to use the address of the variable without making a pointer to the variable in the C/C++ code?
 
es
70
0
I think the main problem is the compiler doesn't (can't) know where 'result' is at compile time as it is in stack memory therefore where it actually lands is calculated by the two moves using fancy addressing mode tricks (like addition). Try declaring 'result' as a static (assuming you don't need multithreading blah blah blah). The additional benefit is you won't have to return result by copy either. As for vin, I'll bet that the first move is only for typing and if you check the optimized assembly output of the compiler it will be gone.

"Premature optimization is the root of all evil" - Donald Knuth
but playing with optimized assembly is fun...
 

Related Threads for: Help: Inline assembly (SSE) slowdown

  • Last Post
Replies
2
Views
2K
  • Last Post
Replies
2
Views
6K
  • Last Post
Replies
2
Views
7K
Replies
8
Views
3K
Top