Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » compilling with MMX instuctions ?

This thread is locked; no one can reply to it. rss feed Print
compilling with MMX instuctions ?
Pavel Hilser
Member #5,788
April 2005
avatar

I often read here advices to compile using MMX instructions. I though this is done automatically, but seems like I'm missing some info ???

If MMX instuctions need to be "turned on", where and how do i do it ?

(using WinXP with MinGW and latest allegro)

EDIT:
I found something in my DEV-C++, i turned on the MMX instruction and recognized some performance incerease (from 120fps to 130fps).

But still, what setting is recommended ? SSE or MMX ? What will happen on CPU withouth this instruction?

_____________________________________
Mein Cannon - see my new 2d game

ReyBrujo
Moderator
January 2001
avatar

When you create Allegro library, it will check if your compiler has MMX and SSE capabilities in two tests, mmxtest and ssetest. If it supports, it adds MMX and SSE support automatically. If you are compiling under MinGW, you can go after compiling inside obj/mingw, and seek a file named asmcapa.h. In my case, it says:

#define ALLEGRO_GENERATED_BY_MAKEFILE_TST
#define ALLEGRO_MMX
#define ALLEGRO_SSE

If your compiler doesn't support any, that line will be missing.

So, nothing to worry, it is turned on by default if your compiler supports it (note that it doesn't mean your computer supports it).

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Oscar Giner
Member #2,207
April 2002
avatar

But that only applyes to allegro itself (and only the asm routines). If you want the compiler to generate MMX/SSE code for your project you have to enable it. The problem is that your program then won't work on CPU's without these instruction sets. MMX is a good option, since any x86 computer less than 7 years ols will have it.

A J
Member #3,025
December 2002
avatar

which compiler do you use ?

MSVC has a "Enhanced Instruction Set" field in the project settings, C++, Code Generation.

GCC(mingw) uses the following flags :
-mmmx -mno-mmx
-msse -mno-sse
-msse2 -mno-sse2
-msse3 -mno-sse3
-m3dnow -mno-3dnow

___________________________
The more you talk, the more AJ is right. - ML

Kitty Cat
Member #2,815
October 2002
avatar

But as noted, using such options will require the target computer to have those instructions available. My 1.1GHz AMD doesn't have SSE. Just MMX and 3DNow (and AFAIK, no Intel chips have 3DNow). IF you want to do it, listen to Oscar. MMX might be a good one to enable as most people have that.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

BAF
Member #2,981
December 2002
avatar

3DNow is AMD. My old 366mhz K6-2 that is in my linux fileserver has 3dnow.

A J
Member #3,025
December 2002
avatar

*WARNING* you cant run MMX/SSE code on non-MMX/SSE systems.

and its not easy to warn using a MessageBox() in the app; things like that aren't even guaranteed to work.

___________________________
The more you talk, the more AJ is right. - ML

Kitty Cat
Member #2,815
October 2002
avatar

AJ:

Oscar Giner said:

The problem is that your program then won't work on CPU's without these instruction sets.

And I said:

But as noted, using such options will require the target computer to have those instructions available.

:)

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Fladimir da Gorf
Member #1,565
October 2001
avatar

It's best to compile two versions of the program - one with mmx and sse enabled and one without them. That way you can make sure that everyone can run the program.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

A J
Member #3,025
December 2002
avatar

KittyCat, and i said "**WARNING** you cant run MMX/SSE code on non-MMX/SSE systems." :P

___________________________
The more you talk, the more AJ is right. - ML

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

It's best to compile two versions of the program - one with mmx and sse enabled and one without them.

Could always go for three.. w/ MMX, w/ MMX+3DNow, w/ MMX+SSE. Would be a shame if I couldn't use an enhanced version because I only have MMX and 3DNow.

With some clever coding, you could check what to use in real time (check Allegro's cpu_capabilities), and put it all in one EXE.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

A J
Member #3,025
December 2002
avatar

and what optimziztion level do you compile that EXE with ?

___________________________
The more you talk, the more AJ is right. - ML

Kitty Cat
Member #2,815
October 2002
avatar

The files with the functions in question, you'd compile with nothing, then with -mmmx then with -mmmx -m3dnow, etc, with each pass adding _mmx or _mmx_3dnow to the end of the functions. Then do:

if((cpu_capabilities&(CPU_MMX|CPU_SSE)) == (CPU_MMX|CPU_SSE))
   function_mmx_sse();
else if((cpu_capabilities&(CPU_MMX|CPU_3DNOW)) == (CPU_MMX|CPU_3DNOW))
   function_mmx_3dnow();
else if(cpu_capabilities&CPU_MMX)
   function_mmx();
else
   function();

Or, you can use function pointers and set them up. You'll incur some hit from the branching (though it'll be constant, so the CPU should predict it well enough) though, but you can make it so each "optimized" function calls other optimized functions without needed to recheck. eg:
when compiled with -DEXT=_MMX_3DNOW:

void some_other_funcEXT();
void some_funcEXT();
{
  blah_blah;
  some_other_funcEXT();
}

So you'd only need to check when "entering" the optimized functions. How much you want to optimize in this way is up to you.. you can optimize everything excluding main, and have that select the properly optimized function for the main loop. But of course, this'll seriously bloat your code, so you need to determine how much would be beneficial.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Hrvoje Ban
Member #4,537
April 2004
avatar

Or you could build couple of executables using different optimization and have loader detects which instructions are supported by CPU and run appropriate executable.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I've done this with raw graphic code (no Allegro):

int mmx_available; //equivalent to allegros cpu bits

extern void mmx_blit(void);
extern void genreg_blit(void);

void (blit *)(void);

//during initialization
if(mmx_available)
blit = mmx_blit();
else
blit = genreg_blit();

//in game loop
blit();

Of course this depends on not having huge chunks of code that differ, but the 90/10 rule implies that optimizing the whole thing/outer loops is a waste of time.

[EDIT]
I have an AMD K6-2, and -march=k6-2 usually runs slower than -march=pentium (!)

They all watch too much MSNBC... they get ideas.

Neil Walker
Member #210
April 2000
avatar

I've never really understood all this MMX stuff with allegro. is it simply if you create a DLL with MMX turned on then people with MMX computers automatically have the optimised functions if you give them the dll?

If so, then there will be MMX and non-MMX dll's out there and no one will be any the wiser whether they could increase their performance or not. So when you download the DLL from allegro.cc how do you know which has been placed there?

Neil.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Arthur Kalliokoski
Second in Command
February 2005
avatar

IIRC, you don't simply "turn on" MMX, you have to use the special instructions (which will cause errors if you don't specify the compiler flag). Maybe in a few years gcc will be able to use them for general purpose stuff like it can use conditional moves now. (Pentium Pro stuff)I haven't used those special instructions in C code myself, but I remember seeing them somewhere in "info gcc". Also, Doesn't M$ QuikView show the functions in a dll?

They all watch too much MSNBC... they get ideas.

Neil Walker
Member #210
April 2000
avatar

if thats the case then perhaps during compilation if a windows dll is being created then with the 'Product Version' propery of the dll, instead of simply saying '4.0.3' why not it be set as '4.0.3 MMX optimised' or '4.0.3 non-MMX optimised' ?

Neil.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

View Profile
IIRC, you don't simply "turn on" MMX, you have to use the special instructions

Actually, yes you do. The compiler will produce asm code that has MMX instructions in it. You can use the special instructions as well if you wish to have more control of how things are done.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Arthur Kalliokoski
Second in Command
February 2005
avatar

tsk. I suppose I need to look at my info again, and if it says what I thought, grab a new version. Sorry for the bad.

They all watch too much MSNBC... they get ideas.

Matt Smith
Member #783
November 2000

Quote:

and its not easy to warn using a MessageBox() in the app; things like that aren't even guaranteed to work.

yes it is, because you put the check in main.c which you compile with all the cpu flags off, and link with the rest of the program which is compiled with them on.

Kitty Cat
Member #2,815
October 2002
avatar

int main()
{
   if(allegro_init() != 0)
   {
      fprintf(stderr, "Error initializing Allegro: %s\n", allegro_error);
      return 1;
   }
   if((cpu_capabilities&(whatever)) != whatever)
   {
      allegro_message("Your CPU capabilities are teh suck!");
      return 1;
   }
   return my_main();
}
END_OF_MAIN()

Put that in a seperate file and compile it without any mmx/sse/3dnow flags.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Arthur Kalliokoski
Second in Command
February 2005
avatar

Fladimir, could you please give me an example? I looked all through gcc info (gcc 3.4.3) and it seemed to imply that MMX and 3DNow were "made available" by -mmmx -m3dnow etc. Grepping the Allegro source for "mm0" through "mm7" only found *.S files, and objdump in the /obj directory only found files that matched the .S files. I also tried running reams of other code through gcc with -march=k6-2 -mmmx -m3dnow -S and didn't get any mm(n). The docs do say that sse - sse2 instructions are used automatically and I could indeed find xmm0 etc after using the right compiler switches, although trying to compile to exe made as bomb out on something called XMMWORD. If you could give me an example it'd really be nice, else I'll have to keep doing it by hand with NASM...

(The builtins do allow you to use mmx and 3dnow, but it's so hairy with all those required unions, typedefs & stuff like __builtin_gcc_pfadd it's worse than asm! And I couldn't find an emms equivalent for mmx without 3dnow so I had to write an asm inline to avoid NAN's trying to print out the results to see if it worked.)

They all watch too much MSNBC... they get ideas.

Go to: