Announcement

Collapse
No announcement yet.

High Speed Graphics DLL

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lance Edmonds
    replied
    Very close! The compiler actually optimizes the loop (decrementing the counter for the same number of counts) if there is no Basic code inside the loop that references the loop counter. This is because counting down is actually slightly faster than counting upward.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Peter Manders
    replied
    Regarding FOR NEXT loops:

    I remember an explanation that, if the loop variable is used within the next couple of statements after the loop, the loop counter is implemented as expected.
    However, if the loop counter isn't referenced right after the loop, the counter will decrement instead, in order to squeeze out an extra couple of clock ticks.

    Maybe that's what's affecting your loop timing results?

    Peter.


    ------------------
    [email protected]

    Leave a comment:


  • Daniel Corbier
    replied
    Chuck, I tried the code that you posted, and indeed I got similar
    results to what you mentioned (even though you originally meant
    to show the opposite). It does show something interesting,
    although maybe something different than what you had in mind.
    When you change the order around, you'll notice that the timer
    prints out the speeds in the very same order. This would
    suggest that the "Next {var}" syntax is not what's making
    the difference.

    I have gotten into the habit of always storing timed results
    in variables before displaying them to the screen, in order
    to get more accurate values. I think the Print statement itself
    skews the timer's result. In this case, instead of
    "Print Timer - t", you would do "t1 = Timer - t" after the first
    loop, "t2 = Timer - t" after the second, and "t3 = Timer - t"
    after the third. And then at the very end "Print t1; t2; t3".
    When you do this, you'll get a more accurate reading. You'll
    notice that the values of t1, t2, and t3 in this case are about
    the same.

    My guess is that when the Print statement is invoked
    directly with the Timer statement, it adds a delay to the result.
    The first timed block prints a value that's slower than its
    actual speed. But at the same time, while Windows is handling the
    first Print statement, the next block gets a head start (it
    doesn't have to wait for Print to finish before continuing), so
    that one prints a value that's faster than its actual speed. The
    head start gain is lost by the time you start the final block, so
    you get a result similar to the first one. This is just my guess
    of what's going on.

    ------------------
    Daniel Corbier
    UCalc Fast Math Parser
    http://www.ucalc.com

    [This message has been edited by Daniel Corbier (edited March 18, 2001).]

    Leave a comment:


  • Tom Hanlin
    replied
    First, grasshopper, one must learn to describe his code to himself as if he were a stranger.
    Learning how to divide the check afterwards is left as an exercise for the student.

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Chuck de Young
    replied
    There is a fine science fiction story called "The Stars
    My Destination" (by Alfred Bester, I believe) in which
    the plot resolves around a person seeing the message he
    expected rather than the actual meaning. It is only after
    I relooked at the post that I noticed the code and the
    results I posted actually "supported" the opposite
    "conclusion" from the one I drew.

    Folks, when I posted this I thought the inner loop was
    the one without "redundant Next {Variable}", now I see
    it was the outer loops. As Lance pointed out the whole
    point was mistaken, but the example should never have
    been seen as supporting the point I thought I was making.

    I have long known that describing your logic to someone else
    will frequently result in a "Eureka" flash. Programmers know
    how valuable a "second set of eyes" looking at code can be,
    but I am shocked by just how blinded I was by what I expected.
    I know mistakes rarely survive the scrutiny post on this BBS
    receive, perhaps I should post all my code up here for review!


    ------------------

    Leave a comment:


  • Lance Edmonds
    replied
    Chuck, your example does NOT show any advantage with specifying or omitting the loop variables in the NEXT statement, since they are essentially 'ignored' by the compiler (they are place-holders only!).

    Repetitive execution tests of your code will reveal that your timing tests are far from conclusive or accurate.

    The most important advantages for FOR-NEXT counters is to use Register Variables in the inner-most loop counters.

    However, please note that the original question(s) in this thread are in relation to 16-bit PB/DLL 2.0, and register variables are not provided by that compiler.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>

    Leave a comment:


  • Chuck de Young
    replied
    Avoid the redundant Next {Variable} syntax.
    Code:
    Option Explicit
    
    Function PbMain() As Long
    Dim T As Double
    Dim XLoop As Long, y As Long, x As Long, l As Long
    t = Timer
    For xloop =1 To 100
      For y = 1 To 100
        For x = 1 To 100
          For L = 1 To 100
          Next
        Next
      Next
    Next
    Print Timer - t
    t = Timer
    For xloop =1 To 100
      For y = 1 To 100
        For x = 1 To 100
          For L = 1 To 100
          Next L
        Next x
      Next y
    Next xloop
    Print Timer - t
    t = Timer
    For xloop =1 To 100
      For y = 1 To 100
        For x = 1 To 100
          For L = 1 To 100
          Next
        Next
      Next
    Next
    Print Timer - t
    WaitKey$
    End Function
    The above code results in :

    1.40200000000186
    .701000000000931
    1.40200000000186

    about a factor of 2.

    Chuck

    ------------------

    Leave a comment:


  • Peter Manders
    replied
    Tyrone,

    Please use the [ CODE ] tags when posting code. It's impossible for me to read it like this.

    Anyway, you can optimize further by replacing xp + yp * pWidth with a counter that gets incremented by an appropriate amount.

    As soon as I can read your code I'll try to find where it fails, because there cannot be that great a difference in loop timing, as Bob Zale just said.


    Peter.


    ------------------
    [email protected]

    Leave a comment:


  • Bob Zale
    replied
    Folks,

    The notion that For/Next Loops are noticeably slower than any other type of looping structure has no basis in fact. It simply isn't so. Any observation to the contrary is some sort of mis-perception. That's a guarantee.

    Please don't run out and start changing all your code... Removing For/Next Loops won't make it any faster.

    Regards,

    Bob Zale
    PowerBASIC Inc.



    ------------------

    Leave a comment:


  • Tyrone W. Lee
    replied
    Tom H..

    What are u talking about?! The code I posted in the ENTIRE program..
    Its a sample of nested loops not using For/Next statements.


    There is a correction to the code which I've included.. Here
    is a sample of the fixed code.. I forgot the = sign within
    my While/Wend statments.. I added the equal sign and rendered the
    Screen at blazing speeds.. The routine WORKS.. It copies data from
    one location to the next.


    Sub FastTest () EXPORT
    Dim x1 as Long, y1 as Long, x2 as Long, y2 as Long
    Dim yl as Long, xloop as Long
    Dim ptrScreen as WoRD PTR, pWidth as Long


    'Actual Ray Variables
    Dim xchange as Long, ychange as Long
    Dim xp as Long, yp as Long, ray as Long, ray_seg as Long, ray_height as Long
    Dim x as Long, y as Long, h as Long
    Dim ray_xchange as Long, ray_ychange as Long
    Dim count as long, lowest_change as Long
    Dim x_Step as Long, y_Step as Long


    ptrScreen = VARPTR(Screen(0,0))

    xloop = 0
    While xloop < 1000
    While yl < 1024
    x1 = 0 : y1 = y
    x2 = 768: y2 = y
    pWidth = 768


    ray_xchange = x2 - x1
    x_step = Sgn(ray_xchange)
    ray_ychange = y2 - y1
    y_step = Sgn(ray_ychange)

    xp = x1
    yp = y1


    If ray_xchange < ray_ychange Then
    lowest_change = Abs(ray_xchange)
    Select Case lowest_change
    Case 0
    ray_seg = Abs(ray_ychange)
    Case Else
    ray_seg = Abs(ray_ychange / lowest_change)
    End SELECT

    ray = 0
    While ray <= lowest_change
    count =1
    While count <= ray_seg
    @ptrScreen[xp + yp * pWidth] = 0
    yp = yp + y_step
    incr count
    Wend
    xp = xp + x_step
    incr ray
    Wend

    Else
    lowest_change = Abs(ray_ychange)
    Select Case lowest_change
    Case 0
    ray_seg = Abs(ray_xchange)
    Case Else
    ray_seg = Abs(ray_xchange / lowest_change)
    End SELECT

    ray = 0
    While ray <= lowest_change
    count =1
    While count <= ray_seg
    @ptrScreen[xp + yp * pWidth] = 0
    xp = xp + x_step
    incr count
    Wend
    yp = yp + y_step
    incr ray
    Wend
    End if

    incr yl
    Wend
    incr xloop
    Wend
    End Sub


    For/Next loops will appear to run as fast as While/Wend loops but
    they don't.. Anyone who wants to debate this with me can address
    these facts..

    First - A For/Next loop is designed for precision - NOT itteration
    The loops I am doing is merely for the # of times an operation
    is run.. So by simulating a counter of your own, your are
    bypassing the need for the system to keep track of the
    itteration. PLUS-

    Sending an Integer to a For/Next loop DOESN'T mean that the
    system will treat it as an integer.. We already stated that
    using Single/Floating point values is slower.. So Consider this
    code..

    For x = a to b Step b/x
    Next x

    Even if the values a and b are orginally integers, the system has
    uses Floating point math to allow for the precision of the Step.
    Even if the step is an integer, it would likely be thought the
    the conversion takes place BY DEFAULT.

    Furthermore.. The downfall of For/Next loops is only apparent
    when using Nested For/Next loops.. And it WILL bring your machine
    to a screeching HALT!.. In the code I posted before, I can
    count from

    Try this code:

    For xloop =1 to 90000000
    For y = 1 to 768
    For x = 1 to 1024
    For line = 1 to 50
    Next line
    Next x
    Next y
    Next xloop

    And compare it to the code I displayed and see which one is faster..
    I am sooo sure of my design, I won't even include all the work
    that my previous routine does..



    ------------------
    Explorations v3.0 RPG Development System
    http://www.explore-rpg.com

    Leave a comment:


  • Michael Ritter
    replied
    Tyrone,

    For/Next loops are executing slightly faster on average than
    While/Wend on my P3 although the results I have are very close
    in both cases. I used my own test code, not the source you
    posted. I did not have time to study your code but would guess
    that some of your inner loops may not be executing. My test code
    is quite large because I was experimenting with Goto so I wont
    post it unless someone wants it.

    Cheers,

    Michael

    ------------------

    Leave a comment:


  • Tom Hanlin
    replied
    Without the whole program, that code snippet does little good, although it
    does pose the question as to whether the bounds of SCREEN() are being passed.

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Tyrone W. Lee
    replied
    Nope.. no mis-calculations in timing All my results are correct..

    The deal is this.. On Pentium chips STAY AWAY from For Next Loops.

    I took this routine..

    Sub FastTest () EXPORT
    Dim x1 as Long, y1 as Long, x2 as Long, y2 as Long
    Dim yl as Long, xloop as Long
    Dim ptrScreen as WoRD PTR, pWidth as Long


    'Actual Ray Variables
    Dim xchange as Long, ychange as Long
    Dim xp as Long, yp as Long, ray as Long, ray_seg as Long, ray_height as Long
    Dim x as Long, y as Long, h as Long
    Dim ray_xchange as Long, ray_ychange as Long
    Dim count as long, lowest_change as Long
    Dim x_Step as Long, y_Step as Long


    ptrScreen = VARPTR(Screen(0,0))

    xloop = 0
    While xloop < 1000
    While yl < 1024
    x1 = 0 : y1 = y
    x2 = 768: y2 = y
    pWidth = 768


    ray_xchange = x2 - x1
    x_step = Sgn(ray_xchange)
    ray_ychange = y2 - y1
    y_step = Sgn(ray_ychange)

    xp = x1
    yp = y1


    If ray_xchange < ray_ychange Then
    lowest_change = Abs(ray_xchange)
    Select Case lowest_change
    Case 0
    ray_seg = Abs(ray_ychange)
    Case Else
    ray_seg = Abs(ray_ychange / lowest_change)
    End SELECT

    ray = 0
    While ray < lowest_change
    count =1
    While count < ray_seg
    @ptrScreen[xp + yp * pWidth] = 0
    yp = yp + y_step
    incr count
    Wend
    xp = xp + x_step
    incr ray
    Wend

    Else
    lowest_change = Abs(ray_ychange)
    Select Case lowest_change
    Case 0
    ray_seg = Abs(ray_xchange)
    Case Else
    ray_seg = Abs(ray_xchange / lowest_change)
    End SELECT

    ray = 0
    While ray < lowest_change
    count =1
    While count < ray_seg
    @ptrScreen[xp + yp * pWidth] = 0
    xp = xp + x_step
    incr count
    Wend
    yp = yp + y_step
    incr ray
    Wend
    End if

    incr yl
    Wend
    incr xloop
    Wend
    End Sub


    And ran it on my Pentium 1Ghz and got BLAZING results... If Change the
    While/Wend to For/Next commands the machine croaks..

    Understand, I am not talking about a small decrease in performance,
    The speed difference is soo slow, its almost NOT working..

    On my Intel Pentium 1Ghz, I can run this iteration well over 2000 times
    in a second.. (which I would expect for a 1Ghz considering my 380Mhz
    can run it 1000 times)

    But if you change the While/End loops to For/Next it can barely
    run the SAME code 80 times.. (That type of degrading performance
    really makes Intel chips look bad..) I'm convinced now more than
    ever than AMD is a far better chip. 2000 times vs 80 times is a big
    difference - considering I only changed the use of my choice
    in looping commands..

    I will test this new routine on my AMD when I get home.. To see if
    there is a performance drop for While/Wend commands but I doubt it.

    The only other possibility (if its not the Intel chip) is that its
    PowerBasic's compiler.. But I don't want to point fingers haha PB is great..

    Maybe this test could be a PB bug, and might be something to
    look into. But for now, I'm blaming Intel until you guys say
    otherwise..

    If you don't believe me.. the code is there ^^ test it yourself..


    I just maxed out the outer most loop with this line:

    While xloop < 90000000

    And the code took almost a complete second on my Pentium 1Ghz.. So
    What would you say to a performace of 80 times a second as opposed
    to 90000000 - Yeah... 90 million times a second with While/Wend
    loops as opposed to 80 with ForNext.. (something is wrong here.)

    ------------------
    Explorations v3.0 RPG Development System http://www.explore-rpg.com

    [This message has been edited by Tyrone W. Lee (edited March 14, 2001).]

    Leave a comment:


  • Tom Hanlin
    replied
    The mere change to a pointer here should have negligible effect... and yes,
    certainly all Pentiums have math processors built in. It seems likely that
    there's a misunderstanding involved in the timing calculations somewhere.


    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Tyrone W. Lee
    replied
    Apparently not...

    I ran this high speed graphics code on my AMD380Mhz and was
    experiencing 80 frames in about 8 second.. I commented the
    line out that referenced the Screen() array and the system
    blazed.. I changed this reference to a pointer ptrScreen[px + py * Width]
    And was able to generate 1024x768x1000 (1000 frames per second!)

    I then, come to work where I have a PentiumIII 1Ghz machine and
    attempt to run the same code... I can barely get 80 frames per second!

    I comment out the reference to any Screen variables and allow
    the computer to just add numbers within the inner loops. The
    machine shows NO increase in speed. Apparently there is NO - Math
    coprocessor on Pentium chips.

    I will run this test again, because its very hard to believe
    my 380 out-performed a 1Ghz, but regardless of my 380Mhz performance.
    I would expect ALOT more from a 1Ghz machine.. I think Pentiums really
    ****!

    If anyone would like to see this code and explain to me WHY there
    is such a big difference please respond..


    ------------------
    Explorations v3.0 RPG Development System
    http://www.explore-rpg.com

    Leave a comment:


  • Eric Pearson
    replied
    > have the math co-processor build it which would explain...

    I'm not a chip expert, but I was under the impression that the last major chip that did not have a math coprocessor was the 386. The 486 had a "stripped down" version -- 486-SX? -- that didn't have coprocessors, but 100% of the Pentiums and above do. Or so I thought. Am I wrong?

    -- Eric


    ------------------
    Perfect Sync Development Tools
    Perfect Sync Web Site
    Contact Us: mailto:[email protected][email protected]</A>



    [This message has been edited by Eric Pearson (edited March 14, 2001).]

    Leave a comment:


  • Tyrone W. Lee
    replied
    Well AMD's have the math co-processor build it which would explain
    why the performance is uniform..

    Regarding speed.. If you havent read the thread "High Speed Graphics Pt. 2" -
    I have made some MAJOR advancements on the original code..

    I was able to produce 1024x760x1000 using a Pointer variable
    reference to the Screen() array. Yea, thats 1000 frames per second on an
    AMD 380Mhz!! This is the kinda speed I'm looking for..

    I posted the code on that thread if anyone is interested..

    Thanks Again Guys! This is really going to help my game project!

    ------------------
    Explorations v3.0 RPG Development System
    http://www.explore-rpg.com

    Leave a comment:


  • Tom Hanlin
    replied
    AMDs are not guaranteed to be faster than Pentiums. It varies "depending". My tests
    suggest that AMDs provide more uniform performance, though: they seem less likely
    to be dramatically affected by tiny changes in code. YMMV.

    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Leave a comment:


  • Tyrone W. Lee
    replied
    I have always been a big fan of AMD processors.. and this little code
    benchmark test will show why...

    I took the sample code and compiled it in PB6.0 On my AMDK2 380Mhz machine
    and here are the results I got.

    Integers:
    Flat Variables - 8.78 seconds
    UDT Variables - 7.58 seconds

    Long Variables - 6.527 seconds
    UDT Variables - 6.703 seconds..

    The difference in Flat vs UDT variables seems to be not-important but there
    was a whole second difference in the Int vs use of Long datatypes.

    But even this time difference isn't as great at the 12second vs 6 second
    example shown on a Pentium of comprable speed. Wonder why?!?


    Either way.. At 400Million iterations in 12 seconds is still 33 million
    assigned pixels per second.. (I only need 25million) Any code designed
    will soar on and AMD with Integer UDT's, and lag a bit on a comprable
    Pentium....



    ------------------
    Explorations v3.0 RPG Development System
    http://www.explore-rpg.com

    Leave a comment:


  • Peter Manders
    replied
    Tyrone,

    don't forget to post a bit of that time critical code once you're happy with it.

    I'm sure some readers here would like to see if they can squeeze more performance out of it. I think it would make an interesting discussion.

    A lot of good tips might come out of it for all of us.

    Peter.


    ------------------
    [email protected]

    Leave a comment:

Working...
X