Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimization: what are sidetable_release() and sidetable_retain()?

In my OpenGL loop, Instruments is showing a total of 14% of my processor time in my particle processing loop going to objc_object::sidetable_release(bool) and objc_object:sidetable_retain(). This is significant, because the loop is using 100% of a CPU on an iPhone 5.

I'm wondering if there's a way I can reduce this. I don't know what causes it, and I don't see these in very many of my methods. I think they are related to doing a fast enumeration of an array of objects.

Here is what the offending method looks like:

-(void) updateWithTime:(ccTime)dt sceneHeightAboveHorizon:(CGFloat)yMax{
    _elapsed = (_elapsed+dt) ;

    float farTotalWidth = EQ_SCENE_WIDTH + 2*EQ_SIZE_FAR;
    float farHalfWidth = farTotalWidth/2.0;

    for (MyParticleData *data in self.farParticleData){

        //Calculate position
        float newX = data.pos.x + data.xVelocity * dt;
        if (newX > 1)
            newX -= 1;

        float newY = data.y0 + EQ_A_FAR*sin(EQ_F_FAR*_elapsed+data.phasePosition);

        data.pos = cc3v(newX,newY,0);
        //Apply new position to sprites
        data.sprite.position = cc3v(newX*farTotalWidth-farHalfWidth, newY*yMax, 0);
        data.reflectedSprite.position = cc3v(data.sprite.position.x,-data.sprite.position.y,0);

        //Calculate color
        float f = MIN(14, MAX(data.pos.x*14.0, 0));
        ccColor4F newColor = cycBlendColors(self.settings.eqColumnColors[(int)f], self.settings.eqColumnColors[(int)f+1], f-(int)f);
        float colorAmp = MAX(0, (sin(data.frequencyColor*_elapsed+data.phaseColor)+1)/2.0);
        newColor = cycScaleColor(newColor,colorAmp);
        colorAmp *= colorAmp;//the alpha (white component) should be squared twice
        newColor.a *= colorAmp*colorAmp;

        //Apply new color to sprites
        data.sprite.color4F = newColor;
        data.reflectedSprite.color4F = cycScaleColor(newColor, self.settings.eqReflectionBrightness);

    }
}
like image 556
Tenfour04 Avatar asked Nov 03 '13 02:11

Tenfour04


1 Answers

I'll try and psychically debug here -

1) You have ARC enabled

2) Some of the intermediate variables in your expressions (ex. data.sprite, self.settings) are Objective-C objects

3) One or more of these intermediate objects are weak or atomic (or are themselves accessing weak or atomic properties), both of which will require extra retain/release handling when accessed. - IIRC atomic properties won't involve the side table rigamarole, just normal autoreleasing, but no guarantees on that.

I would try assigning some/all of these references to a local (on the stack) variable before enumeration, and inside your loop use the local references exclusively. This will have the added benefit of shaving off some accessor time from your loop as well.

If you know these references will remain strongly referenced through the entire enumeration 100% of the time, then you can use the __unsafe_unretained specifier on your local variables, which will (mostly) prevent any ARC shenanigans whatsoever from occurring in this method.

like image 105
Steazy Avatar answered Nov 18 '22 11:11

Steazy