On Mar 24, 2006, at 4:32 PM, IOhannes m zmoelnig wrote:
usually only one single instance of GemSIMD will be created during the life-cycle of Gem, serving as an initialization of the cpu-check. this instantiation is done in GemMan (right after the splash-screen).
...splash screen? I saw this committed, but what's the idea of it? Is this something to come up when Gem is loaded? Or when a gemwin is opened?
now GemSIMD provides a static variable "cpuid" which shows the capability of the used cpu. this variable could be accessed like the static variables in GemMan (e.g. GemMan::simd). however, i have done it via a (static) function call to GemSIMD::getCPU(), because this ensures that the variable cannot be modified from outside. instead there is a another (static function GemSIMD::requestCPU() where you could set the cpuid (as returned by getCPU()) to something else that is supported by your cpu. e.g. a G5 could be either altivec OR generic. an amd64 could be either sse2 OR mmx OR generic. usually getCPU() will return the best instruction set that is supported.
...this sounds fine, but the GemSIMD::getCPU() static variable in GemPixUtil.cpp isn't working for me: it always remains 0, whereas GemSIMD::cpuid does show "3"...perhaps we should just make it defined in GemMan like most things, then "extern static int m_simd;" in source files when needed?
why would somebody want this? i am not sure. it is just possible. of course it is great if you want to do speed comparisions - but that is normally not important outside of the development. another aspect is, that sometimes SIMD and non-SIMD implementations do not behave exactly the same (though they should); by being able to chose non-SIMD operation, people have some control on what is going on.
...ok, I'm all for doing it if it buys us more flexibility at no cost, even if we rarely use it...
how do the actual processing routines get called? currently only GemPixObj and the imageStruct-class (GemPixUtil) make use of this SIMD-system. there behaviour is independent (though similar). ..in GemPixObj there is (historically) a m_simd flag which is used to select the processing-implementation. this can be set via a "simd $1" message to the pix-object. this way you can turn on/off the level of optimization individually for each object. the m_simd flag is modified via the GemSIMD::requestCPU(), in order to assure that it is always supported by the used cpu. ..in imageStruct there is a global variable, which also is called m_simd (but does not influence the one in GemPixObj); this variable is global (to the file)/static because i didn't want to have an extra variable for each image denoting, whether this image should be processed with/ out SIMD. A better solution would have been, to use GemSIMD::getCPU() instead of m_simd. it was just a vague idea of performance loss that led to the current solution. (i am also not sure, whether it is significantly slower to use a function-call to getCPU() instead of directly accessing cpuid: chances are high it is!)
...I don't know what the function overhead would be, but isn't it minimal when dealing with a basic accessor function to a c++ class member variable? Would this be a candidate for inline-ing?
jamie