Skip to main content
GameDev.net gamedev.net
🔒 Locked

bits as float - "MOVD xmm0, eax" and MSVC nonsense

Started by tanzanite7 Apr 22, 2020 at 12:31 PM 17 replies 14.4k views
Original Post
tanzanite7
tanzanite7

While checking out something'n'other via compiler explorer i noticed that MSVC does

mov [temp], eax
movss xmm0, [temp]

… instead of just …

movd xmm0, eax

Won't really matter performance wise for me, but still - is there some way to stop MSVC from being an absolute idiot and do the sane thing like every other darn compiler i can find? _castu32_f32 seems to be perfect fit - but is not available in MSVC. Is there something else that could work?

--------------------------------------------

Thought about it a bit more before pressing "post" … and got an idea to solve it. Hm, why not include it and post it anyway - what do you think of it?

float _castu32_f32(int unsigned val) {
    float res;
    _mm_store_ss(&res, _mm_castsi128_ps(_mm_loadu_si32(&val)));
    return res;
}

1. _mm_loadu_si32 - move int into the beginning of a m128i (first 32 bits in m128 are what floats internally are - let's face it, the ancient FPU floats are so horrible that no-one uses them)

2 _mm_castsi128_ps - does nothing (just switches the type sugar coating for the compiler)

3 _mm_store_ss - does nothing (move m128 to float - where the later is internally actually also m128 anyway)

Works perfectly in release, but is terrible (of course) when optimizations are not enabled. Ignoring all the function call code and its extensive checking - this gem remains:

movd        xmm0,dword ptr [val]        // do the thing (_mm_loadu_si32)
movdqa      xmmword ptr [rsp+50h],xmm0  // store it in preparation of doing nothing
movaps      xmm0,xmmword ptr [rsp+50h]  // load to do nothing (_mm_castsi128_ps)
movaps      xmmword ptr [rsp+60h],xmm0  // store it in preparation of doing nothing
movaps      xmm0,xmmword ptr [rsp+60h]  // load to do nothing (_mm_store_ss)
movss       dword ptr [res],xmm0        // store it in result after doing nothing

Amusing. Also, shows/confirms what the compiler sees.

NikiTo
NikiTo

You are brave to read the ASM output of the compiler and post it on the internet. Some people worship compilers as gods. They will feast on your flesh and not even bones will be left.

tanzanite7 said:
Won't really matter performance wise for me,

If i were you, i would just ignore it and keep coding. Too much work to teach a horse fly as a bird.

Juliean
Juliean

tanzanite7 said:
Won't really matter performance wise for me, but still - is there some way to stop MSVC from being an absolute idiot and do the sane thing like every other darn compiler i can find? _castu32_f32 seems to be perfect fit - but is not available in MSVC. Is there something else that could work?

You should file a bug-report/feature-request with microsoft. Show them your code and the compiler-explorer output, as well as the asm generated by other compilers, and maybe have them fix/improve this situation

NikiTo said:
You are brave to read the ASM output of the compiler and post it on the internet. Some people worship compilers as gods. They will feast on your flesh and not even bones will be left.

Ironically, the people who praise compilers over handwritten ASM are the same people that look at the generated ASM in tools like compiler explorers, and realise that eigther the result is already pretty optimal, or can be improved by the compiler-writers. In the end of the day, compilers can produce the same/better assembly than you. Even if they won't today for a given code, there is no reason why the same procedures you use for turning source into ASM can not be implemented as an optimization-step in the compiler. I hope that one day you realise that.

tanzanite7
tanzanite7

Some surprising results have emerged. Decided to add the _castu32_f32 implementation to my project and used it in random float number generation. For debug purposes also added an alternate implementation for debug build (to keep my massive use of random floating point values to sane speeds when debugging) via preprocessor directives. Which lead me to test it with real code in release build.

Using “vec3 Rng::onSphere(float radius)” for benchmarking - which returns an unbiased random point on given sphere. Including the overhead for fully using the returned vector (to prevent optimizations from cutting anything out) and looping it 10mil times - “(*(float*)&val)” ends up making the whole thing ~8% slower than using my implementation of “_castu32_f32(val)” (both cases in release build with full optimizations of course).

Did not see that coming. Still won't matter performance wise to me … but interesting. That unnecessary memory temporary has surprisingly noticeable impact.

NikiTo said:

If i were you, i would just ignore it and keep coding. Too much work to teach a horse fly as a bird.

Yeah, a bit of a detour down the rabbit hole. I don't even quite remember how i ended up there.

Juliean said:

You should file a bug-report/feature-request with microsoft. Show them your code and the compiler-explorer output, as well as the asm generated by other compilers, and maybe have them fix/improve this situation

NikiTo said:
You are brave to read the ASM output of the compiler and post it on the internet. Some people worship compilers as gods. They will feast on your flesh and not even bones will be left.

Ironically, the people who praise compilers over handwritten ASM are the same people that look at the generated ASM in tools like compiler explorers, and realise that eigther the result is already pretty optimal, or can be improved by the compiler-writers. In the end of the day, compilers can produce the same/better assembly than you. Even if they won't today for a given code, there is no reason why the same procedures you use for turning source into ASM can not be implemented as an optimization-step in the compiler. I hope that one day you realise that.

tanzanite7
tanzanite7

The forums posting interface silently completely broke - as usually. Since it is kind of usual i happened to copy paste my reply out before posting and can now re-add the part that silently evaporated. Won't edit the reply itself as the mess that shows up when i try to edit tells me to stay far away from attempting that.

So, the missing part where i replied about reporting it:

That is a bit of doing, but i have done that before quite a few times already and got stuff fixed as a result - so, i think about it.

NikiTo
NikiTo

Juliean said:
Ironically, the people who praise compilers over handwritten ASM are the same people that look at the generated ASM in tools like compiler explorers, and realise that eigther the result is already pretty optimal, or can be improved by the compiler-writers. In the end of the day, compilers can produce the same/better assembly than you. Even if they won't today for a given code, there is no reason why the same procedures you use for turning source into ASM can not be implemented as an optimization-step in the compiler. I hope that one day you realise that.

I know you don't accept quotes from other people. Only what you believe matters, but here it goes anyways-

https://stackoverflow.com/questions/577554/when-is-assembly-faster-than-c

Definitively nobody in the top 5 answers said “compilers are ALWAYS faster than ASM”. Definitively not what you say. Nothing at all like the things you claim.

Why don't you learn to code in ASM? Maybe you will end up loving ASM if you understand it. I don't suggest you to use it, because it is not so productive as using compilers. Just understand it, before you blame it.

Green_Baron
Green_Baron

@nikito : Why can't you be more relaxed ? Nothing of what you put forward was said by @juliean . Neither did they say or even remotely mean that compilers were allways faster than hand written assembler nor did they claim anything. The deduction that “in the end a compiler can produce better/faster code than you” is a completely valid assertion (note the "can"). And, btw, it is a common place. I must also say, stackexchange is by no means a high level or even trustworthy source, there is so much bunk e.g. on the geoscience or history departments, it is ridiculous.

I have the feeling that your fox/grape metaphor shows signs of psychological projection. To convince me that you're so high above us, why don't you show off one of your assembly creations so we can let it run against a high level version. But please something genuine, not just a Fibonacci sequence …

NikiTo
NikiTo

@Green_Baron Because two weeks ago, Juliean and another 3k reputation member bullied me out of this forum. I know what i am talking about.

(ignoring my quotes a 3rd time, baron?…. Only you and the high reputation members are correct? Eh?

Here it goes another link anyways-

https://www.kaspersky.com/blog/the-history-of-programming/1356/

Let me guess, baron…. The people from Kasperski, Linus Torvalds and the whole Stackexchange are nothing compared to your own opinion and the opinion of the high reputation members you try to seduce. A peculiar personality you have there…)

(I am not going to reveal my real life portfolio here and reveal my real personality here only to show you some of my ASM code that you are anyways unable to read. What will be your next dirty trick, baron? - to tell(to lie to me) me: “your code doesn't compile on my computer, so i can not measure it myself so i don't believe you so you are wrong and i am correct”… )

My posture was always - ASM is faster, smaller but less productive.
If you still debate that claim, i will ignore you, because your level of programming skills and understanding are too low compared to mine. No point of even talking to you.

I can predict what your next comment will be like, saying something about my grammar maybe. But you and I, we both know this is a public place and a lot of other random people will read this and see through the real you.

SuperVGA
SuperVGA
fleabay
fleabay

“The greatest enemy of knowledge is not ignorance. It is the illusion of knowledge.” -Daniel J. Boorstin

🙂🙂🙂🙂🙂<←The tone posse, ready for action.
Bregma
Bregma

tanzanite7 said:
“(*(float*)&val)”

If “val” is anything but a float you're invoking undefined behaviour. You can go ahead and report it as a bug to Microsoft if you want. I can tell you as a compiler developer we get no end of “pleasure” when customers tell us their code containing UB doesn't behave the way they expect it to. “My code is broken you need to fix your compiler!!”

As for why MSVC would write to cache and read it back instead of doing a processor-to-processor transfer directly, it might come down to the way superscalar pipelines work. It can sometime be much much faster to round-trip through the L3 cache than to do onboard conversions between data formats. I make no guarantee that's the case without consulting x86_64 timing tables (and I'm not going to do that if I'm not on the clock) but there are many, many subtleties in today's processors that many people who are not experienced experts consisting partially of silicon themselves might miss. It could also be an artifact of C code containing undefined behaviour. The compiler is allowed to assume your code contains no undefined behaviour and when it does, weird and unexpected things can happen.

Stephen M. Webb
Professional Free Software Developer
NikiTo
NikiTo

I would not report it. First, compiles can not read the thoughts of the coder. They can not get 3 notes music sheet and add the rest of hundreds of notes in order to create the best melody the coder wanted to compose inside his head.

Should we blame a horse for not being able to fly?

Compilers give us productivity. That's why i use a compiler myself.

Second, reporting a bug is to do the job of the compiler programmer. I am not paid to improve the compiler of Intel. They pay to people to do that. Except in the case when i really need for my own interests the bug to be fixed. In which case comes the Third - most probably your bug report will be filed for years or even be ignored by the compiler developers. If the developer has to fix stability-bugs first, he will not even peek into your speed-bug.

This is perfectly normal. Perfectly understandable. I am sure compilers do their best with only 3 musical notes. I have not used ASM myself in years and i wish i dont have to use it. But facts are facts - with ASM i get access to all the musical notes….. then the OS will destroy most of my optimizations by flushing my registers all of the time because of other processes. But this doesn't make ASM slower than a compiler. It is the OS that makes it slower. But again, it is perfectly normal and understandable.

(I can imagine the reaction of some religiously radical compiler developer reading your bug report - “I looked at the ASM output and the produced code is slower than hand written ASM”… LOL just imagine how much and for how long a radical “compiler is faster than any ASM”-type of a dev would swear in your address. How many days the radical compiler developer will be cursing you. Can you imagine it? You do an extra work to file a bug for those people, you show them part of your code and they will send so much so bad vibrations in your address, you could get sick for no apparent reason. I really hope the compiler developers are not radical religious fanatics. But again, i don't mind it how good they do their jobs. Even a bad compiler is good for the purposes of my current project. I need to develop a good algorithm. Tuning my app at the level of produced machine code is the job of other people. They will be paid by their companies to do it, when i am done with my algorithm and sell it. It is not about money, it is about productivity. If i did everything, i would never finish.
I see this is the problem of many people here - they ask how to optimize a 2D game to run at 1200FPS, which is a complete loss of time. They should be spending their time creating the entertainment part of the game, rather than making it get from 800 FPS to 1200FPS(if they want to publish a game someday soon, someday this century))

fleabay
fleabay

NikiTo said:
I see this is the problem of many people here - they ask how to optimize a 2D game to run at 1200FPS

Can you post a link to one of the many examples you have seen? Thanks.

Also, you seem to have a great contempt for compiler programmers. You do know that they are among the best assembly programmers around, right?

🙂🙂🙂🙂🙂<←The tone posse, ready for action.
NikiTo
NikiTo

fleabay said:

NikiTo said:
I see this is the problem of many people here - they ask how to optimize a 2D game to run at 1200FPS

Can you post a link to one of the many examples you have seen? Thanks.

Also, you seem to have a great contempt for compiler programmers. You do know that they are among the best assembly programmers around, right?

There are lot of examples in the forum.

Any good compiler dev is needed to have a great knowledge in ASM. I think a good compiler developer would completely agree with the things i said so far. They offer a product to boost productivity of people. And it is easier to start learning programming in JS, so programming gets more popular the easier and more superficial the language is. Which leads to the situation of many programmers having no idea of programming at all.

In the beginning i made a whole interactive responsible site in Flash without knowing nothing at all about programming. The menus were playable around. I pretended to be a programmer while not knowing what a variable is. I recall the case of a man who was operating Linux serves in his daily job. He was behaving as far superior to everybody else in the class, because he was typing in a terminal. But he did not know you can put more than one LAN adapter to the same computer and use it as a networking machine. He was so shocked to learn it, that he exclaimed out loud: “so you can do that! Wow! Amazing! This opens so many new horizons for me”… the class was facepalming… A lot of people believe they are master programmers for using lambdas, although they can not tell when a lambda is really needed, and when a lambda is just a syntax candy.

The main selling point of node.js was “you can have a server in five lines of code” promoting mediocrity.

I would be not surprised if a programmer after working for 20 years in the industry, does not know what is he doing. It can happen with HLLs.

Claiming "Linux is safer than Windows" or “A good compiled code is faster than any assembly code” are symptoms of having not enough understanding of the matter.

You completely ignore the fact i promote compilers. Never ever in this forum i told nobody to drop a compiler and use assembler. I even strongly discouraged people from using ASM. The thing is, me saying that a good assembler can write faster code than a good C++ coder, triggers some people here for some foxy reasons.

What if a compiler developer decides to write a program in ASM for fun? Will the same person write slower assembler than his own compiler? If you can not understand the complete nonsense of the claim “a good compiler can produce faster code than any assembler”, then you need to keep studying.

fleabay
fleabay

NikiTo said:
I see this is the problem of many people here - they ask how to optimize a 2D game to run at 1200FPS

NikiTo said:
There are lot of examples in the forum.

Why can't you post a link to one of them? I can cut and paste a URL if you don't know how to make a hyperlink.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.
NikiTo
NikiTo

fleabay said:
I can cut and paste a URL if you don't know how to make a hyperlink.

fleabay
fleabay

NikiTo said:

fleabay said:
I can cut and paste a URL if you don't know how to make a hyperlink.

Why did you post a blank quote? Why can't you post a URL as proof of your claim?

🙂🙂🙂🙂🙂<←The tone posse, ready for action.
NikiTo
NikiTo

fleabay said:

NikiTo said:

fleabay said:
I can cut and paste a URL if you don't know how to make a hyperlink.

Why did you post a blank quote? Why can't you post a URL as proof of your claim?

I'm trying! I'm trying!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.