[GEM-dev] gem cvs question: altivec (SIMD) conventions

IOhannes m zmoelnig zmoelnig at iem.at
Wed Oct 1 18:16:51 CEST 2003


hi gemers.

about pix_altivec functions:
right now, altivec support in Gem looks like this:

<snip pix_text.h>

virtual void pix_test :: processImage(imageStruct &image);
virtual void pix_test :: processImageAltivec(imageStruct &image);

</snip>


<snip pix_text.cpp>

void pix_test :: processImage(imageStruct &image)
{
#ifdef ALTIVEC
	processImageAltivec(image);
	return
#else
   // some slow code
#endif
}

void pix_test :: processImageAltivec(imageStruct &image)
{
#ifdef ALTIVEC
   // some fast code
#endif
}

</snip>

now my question: wouldn't it be better to make more use of inheritance ?
and call the altivec-processing directly from GemPixObj, if altivec is 
supported  by the machine ?
i write this with MMX and SSE2 in mind:
i guess, all modern apple-computers have altivec;
all modern pcs have mmx, but only some of them have sse2 (i guess 
pentium-4 only, but amd will support it in the future).
i would rather decide at runtime whether any parallel processing is 
available, and then call the appropriate function. the fallback of all 
those altivec/mmx-functions would of course be the generic-processing.

so i was thinking of something like
<snip GemPixObj.h>

   virtual void 	processYUVImage(imageStruct &image);
   virtual void 	processYUVImageAltivec(imageStruct &image);

</snip>
<snip GemPixObj.cpp>

void GemPixObj :: render(GemState *state){
//...
       switch(state->image->image.format){
//...
       case GL_YCBCR_422_GEM:
	switch (m_haveSIMD){
	case SIMD_ALTIVEC:
	  processYUVImageAltivec(state->image->image);
         break;
	default:
	  processYUVImage(state->image->image);
	}
//...
   }
}
void GemPixObj :: processYUVImage(imageStruct &image){
   processImage(image);
}
void GemPixObj :: processYUVImageAltivec(imageStruct &image)
   processYUVImage(image);
}

</snip>


<snip pix_test.h>

virtual void pix_test :: processImage(imageStruct &image);
#ifdef ALTIVEC
virtual void pix_test :: processImageAltivec(imageStruct &image);
#endif

</snip>


<snip pix_test.cpp>

void pix_test :: processImage(imageStruct &image)
{
   // some slow code
}
#ifdef ALTIVEC
void pix_test :: processImageAltivec(imageStruct &image)
{
   // some fast code
}
#endif

</snip>

GemPixObj::m_haveSIMD could be SIMD_ALTIVEC, SIMD_MMX, SIMD_SSE2 (or 
whatever)

pros (i can think of right now):
code that is the same is rather in the parent-class than in each child.
this would make it possible to turn on/off SIMD on the fly. (probably 
not a very good argument, but handy for profiling / showing the 
advantages of SIMD).
furthermore it would keep the #ifdef-nightmare a bit more clean ( i believe)
the number of function-calls would be reduced by one (at the cost of one 
case-loop)

i don't know whether G5-ALTIVEC-compiles can be executed on G4's - would 
it be possible if the PPC970-code would be capsuled in an if-clause ?

drawbacks:
- a little work to be done (i have already started to do so, but haven't 
yet committed it because i don't know, whether my idea is really good)
- there has to be a naming scheme for SIMD-processing. i have noticed, 
that in PixDualObj's the naming is rather arbitrary: 
pix_subtract::processYUVAltivec() vs. 
pix_chroma_key::processYUV_YUVAltivec()



any comments ?

mfg.as.r
IOhannes





More information about the GEM-dev mailing list