GLBasic forum

Main forum => GLBasic - en => Topic started by: MikeHart on 2010-Feb-18

Title: Why could this routine be crawling on the iphone?
Post by: MikeHart on 2010-Feb-18
Hi folks,

I'm pulling my nonexistant hair out.

Quote//-------------------------------------------------------------------------------------
FUNCTION TBGL_SpriteSetColor%: spriteID%, red%, green%, blue%
//-------------------------------------------------------------------------------------
   IF TBGL_SpriteCount% > 0
      FOREACH TBGL_iSprite IN TBGL_SpriteList[]
         IF TBGL_iSprite.id% = spriteID%
            TBGL_iSprite.iRed#   = red% / 255.0
            TBGL_iSprite.iGreen# = green% / 255.0
            TBGL_iSprite.iBlue#  = blue% / 255.0
            RETURN TRUE
         ENDIF
      NEXT
   ENDIF
   RETURN FALSE
ENDFUNCTION

I'm calling this function in a frame exactly 1 time atm.  The list of the types I am looping through has 10 items. The UDT itself is very big. When I call this function my framerate goes down badly. 1 call and the framerate on the IPhone goes down from 60 to 34. If I uncomment the 3 lines with the division, the framerate stays up. Any idea what could be wrong? After all these years of developing apps and games with various languages, I can't see a reason why these 3 division would be a framerate killer. Is it the mix of types that GLBasic doesn't like?

Any hint is appreciated.
Michael
Title: Re: Why could this routine be crawling on the iphone?
Post by: Kitty Hello on 2010-Feb-18
float to int and vice versa is very expensive. And divisions are, too.
See the C++ code I generate - there's no overhead from me.
Title: Re: Why could this routine be crawling on the iphone?
Post by: BdR on 2010-Feb-26
If you really want to do many divisions for each frame, you can use a lookup table to speed things up. You only keep track of the integer values and don't recalculate the floating point values each time. When you need the floating point value, you use the integer value as an index in the precalculated lookup table.

I assume that in this case you only calculate color values, which are always between 0 and 255 (integer), or between 0.00 and 1.00 (float).

Code (glbasic) Select

GLOBAL PrecalcFloat#[]
DIM PrecalcFloat#[256]

// at program start-up
For i% := 0 to 255
  PrecalcFloat#[i] = i% / 255.0
Next //i

// .. and then when you need the color float values
TBGL_iSprite.iRed#   = PrecalcFloat#[red%]
TBGL_iSprite.iGreen# = PrecalcFloat#[green%]
TBGL_iSprite.iBlue#  = PrecalcFloat#[blue%]
Title: Re: Why could this routine be crawling on the iphone?
Post by: Kitty Hello on 2010-Feb-26
I'd go for an inline in this case. The [] operator is not as quick as a static array in C++
Title: Re: Why could this routine be crawling on the iphone?
Post by: bigsofty on 2010-Feb-26
May help, have you tried turning off Thumb mode for the ARM?
Title: Re: Why could this routine be crawling on the iphone?
Post by: BdR on 2010-Feb-27
Quote from: Kitty Hello on 2010-Feb-26
I'd go for an inline in this case. The [] operator is not as quick as a static array in C++
I didn't know about the INLINE statement, but I guess you mean something like this:

Code (glbasic) Select
GLOBAL TestFloat#
GLOBAL TestIndex%

TestIndex% = 3
TestFloat# = 0

DEBUG "Before INLINE: TestFloat#="+TestFloat#+"\n" // TestFloat#=0

INLINE // do some c++ code
  // the static array
  const double PrecalcFloats[ 5 ] =
  { 0.00, 0.25, 0.50, 0.75, 1.00 };
 
  // check for illegal index values
  if ( (TestIndex >= 0) && (TestIndex <= 5) ) {
    TestFloat = PrecalcFloats[TestIndex];
  } else {
    TestFloat = -1;
  };
ENDINLINE

DEBUG "After INLINE: TestFloat#="+TestFloat#+"\n" // TestFloat#=0.75


I use a 'static' array for the font widths in my current project. This is a glbasic-array which I fill with READ STARTDATA at program start and then when printing a string I read FontWidths[iLetter]. But I guess this INLINE plus a C++ array is faster then?
Title: Re: Why could this routine be crawling on the iphone?
Post by: MikeHart on 2010-Feb-27
Thanks for your suggestion about the thumb mode. I did it already but nothing changed.

So far I am not sure what really the problem is. I use big types. I also use CALLBYNAME in this. Then at one moment I though that it was the RND function that is the reason for the big slowdown. Or the definition of my variables. Then again, using the same sub inside a new project gave no problems. So something is very weird here and this takes to much time to figure out.  Time I could spend on the logic of a game. So I gave up doing this in GLBasic.

Thanks all for your help, I appreciate it.
Title: Re: Why could this routine be crawling on the iphone?
Post by: Kuron on 2010-Feb-27
QuoteAny hint is appreciated.

Mike, the following are hints, not flames  ;)

I don't have an iPhone and offhand I have no idea how customized the ARM is that Apple is using, but in general when it comes to ARM processors:

1.  Most ARMs out there do not have a FPU (floating point unit).  This is emulated via a library for these ARMs.  Like I said, I do not have an iPhone to know how customized the ARM is they are using.  The use of floats is generally considered a no-no and bad form for ARMs.

2.  ARM generally does NOT have native support for for divide instructions.  This is emulated via libraries (one for signed and one for unsigned) which can be up to 100X slower than using the ARM's native shifting operations.  We are talking up to 140 processor cycles for each division operation.  I think you can see the reasons for the bottlenecks you are experiencing.

3.  UDTs.  The ARM generally prefers word-aligned data.  Unaligned data access is considered a no-no and bad form for ARMs.  If it isn't word, it gets emulated.


Some general division tips for ARM (how well they work can depend on how well a compiler is optimized for ARM):



QuoteAfter all these years of developing apps and games with various languages, I can't see a reason why these 3 division would be a framerate killer.

The previous experience is not necessarily beneficial and can sometimes be a hindrance.  It is like driving a car for all of your life and then finding yourself behind the wheel of a tractor trailer.  The previous driving experience does not necessarily make you a good driver of tractor trailers.  There are enough differences that you need to learn some new skills and learn how to approach some things differently.  The previous experience can be a hindrance because it becomes habitual to do things in a way that may not necessarily work well in a new situation.

I hate to sound like Hutch (some will get the joke), but, when supporting a new/different processor you really need to take some time to read through the instructions available for the new processor you are dealing with so you know how to properly write a program that will run efficiently and correctly on that processor.  There is only so much hand-holding a compiler can do for you.

A few years ago, I got back into developing for gaming consoles (custom built, homebrew and vintage).  I routinely deal with PICs, ARMs, AVRs, Propellers, BASIC Stamps, JStamps, 6502s, and some prototypes that aren't on the market yet.  I have to use a completely different approach in programming for each processor.  Most processors have very different features, strengths and weaknesses.
Title: Re: Why could this routine be crawling on the iphone?
Post by: MikeHart on 2010-Feb-27
Thanks Brice for the explanation. It is definately something to think about!  :good:
Title: Re: Why could this routine be crawling on the iphone?
Post by: bigsofty on 2010-Feb-27
The ARM processor used by the iPhone/iPod touch has an extension called VFP for doing fast floating point operations.

This is a good iPhone VFP library, http://code.google.com/p/vfpmathlibrary/ , it may give GLBasic a needed floating point speed boost but interfacing with it is beyond me, I'm afraid.
Title: Re: Why could this routine be crawling on the iphone?
Post by: Kitty Hello on 2010-Mar-02
that's a bunch of matrix and a fast sin() command.
I have a qmath.gbas file in the smaples/common directory. If you use that QSIN, QCOS QSQR commands, they are a lot faster than the accurate commands. But about 5% off the real value.
The iPhone ARM has an fpu, I use it.
Title: Re: Why could this routine be crawling on the iphone?
Post by: MrTAToad on 2010-Mar-02
Another alternative is to use fixed-point maths, a routine I've got in the Code Snippets section somewhere...
Title: Re: Why could this routine be crawling on the iphone?
Post by: Hatonastick on 2010-Mar-10
Even better, you can use my...  Oh hang on, no I haven't written anything yet.  =D
Title: Re: Why could this routine be crawling on the iphone?
Post by: Kuron on 2010-Mar-14
Mike:  The new dual core iphones are supposed to hit next month, it might give you a slight performance boost ;)