Help: Inline assembly (SSE) slowdown

  • Thread starter Thread starter Dissident Dan
  • Start date Start date
  • Tags Tags
    Assembly
Click For Summary

Discussion Overview

The discussion revolves around the use of inline assembly in C++ for implementing SSE instructions within MS Visual Studio.NET. Participants explore issues related to performance penalties caused by the handling of addresses and pointers, as well as optimization strategies for assembly code.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant expresses difficulty in using inline assembly with addresses from C++ other than explicitly-declared pointers, suggesting that this may lead to performance issues.
  • Another participant suggests that compiler options for optimizing for SSE might exist in VS.NET, similar to those in GCC.
  • It is proposed that the base address of a floating point array should be loaded into a register for efficient access, with specific instructions provided for moving data into SSE memory.
  • Concerns are raised about whether the performance penalty from pushing an address onto the stack is significant compared to the SSE instructions themselves, with a recommendation to check the compiled output.
  • Participants discuss the necessity of using CPU registers for addresses and the limitations of the compiler in recognizing variable addresses directly in assembly.
  • One participant suggests declaring the result array as static to avoid issues with stack memory and copying, while also referencing the idea of premature optimization.

Areas of Agreement / Disagreement

There is no consensus on the best approach to optimize the inline assembly code, with multiple competing views on how to handle addresses and performance considerations remaining unresolved.

Contextual Notes

Participants note limitations related to the compiler's ability to recognize variable addresses and the potential impact of stack memory on performance, but do not resolve these issues.

Dissident Dan
Messages
244
Reaction score
1
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: )
 
Computer science news on Phys.org
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.
 
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
 
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:
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 don't know 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?
 
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...
 

Similar threads

Replies
8
Views
3K