Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
CPU vs GPU scrolling
#1
Seeing few members playing with scroll, here comes one small toy suitable to test old laptops ability to scroll fast.
In my case I put to the test my slowest ThinkPad using single-channeled RAM paired with an old HD (not UHD series) shared memory integrated video controller. Old 1366x768 resolutions are targeted as well.

The CPU-driven putimage speed is not good at all, 180 FPS:

   

The GPU-driven putimage speed is superb, 1080++ FPS:

   

The source is attached.

I think the support for hardware rendering is a-must despite CPU renderer already achieving usually more FPS than most modern monitors offer, meaning 165Hz as a bare minimum, and targeting 480Hz. Will add this to my TriMasakari smooth scroller while retaining software rendering as an option. By the way, this summer I got frustrated of tearing (the lag) despite the speed, this hate resulted in writing the best smooth scroller known to me - SSSS, I wrote it in pure C. The V-sync feature is what made it really smooth, with no lag at all. The old SSSS was featured in this video at 9:50 mark:



Attached Files
.bas   CPU-vs-GPU.bas (Size: 6.43 KB / Downloads: 21)
"He learns not to learn and reverts to what the masses pass by."
Reply
#2
As long as we're showcasing speeds and such, allow me to showcase another important way that people often bottleneck a program that they don't even realize they're doing:

Code: (Select All)
'CPU-vs-GPU.bas, example by Johny B. rewritten by Kaze

EnforceFPS = 480
AutoMode = 0 ' should be 1 to autoscroll

Print "Choose "
Print "C] SOFTWARE (CPU RAM) copying"
Print "G] HARDWARE (GPU RAM) copying"
RAMtype$ = UCase$(Input$(1))

If RAMtype$ <> "C" And RAMtype$ <> "G" Then System

imgW = 1200
imgH = 700
winW = Len(" Window: The box is being moved via SOFTWARE/CPU copying. ") * 8
winH = 502
Const winTRA = 110

handle& = _NewImage(imgW, imgH, 32)
Screen handle&
_Dest handle&
Do: Loop Until _ScreenExists: _ScreenMove 3, 3
_Title "For autoscroll press `/1/2/3/4/5/6/7/8/9/0/-/= for different FPS presets; or use A/W/S/D to scroll manually"

'create some software screens
scr_bg = _NewImage(imgW, imgH, 32)
scr_fg = _NewImage(winW, winH, 32)

'draw to the background one, and make a nice pattern
_Dest scr_bg
For i = 1 To 100
Line (Rnd * imgW, Rnd * imgH)-(Rnd * imgW, Rnd * imgH), _RGBA32(Rnd * 255, Rnd * 255, Rnd * 255, Rnd * 255), BF
Next i
'create a hardware screen version of the background
scrh_bg = _CopyImage(scr_bg, 33)
'_FreeImage scr_bg 'we no longer need the software version in memory

'then do the same thing for the foreground
_Dest scr_fg
Line (0, 0)-(winW, winH), _RGBA32(95, 125, 195, winTRA), BF

If RAMtype$ = "C" Then
_PrintString (0, 0), " Window: The box is being moved via SOFTWARE/CPU copying. "
End If
If RAMtype$ = "G" Then
_PrintString (0, 0), " Window: The box is being moved via HARDWARE/GPU copying. "
End If

JuPr

'copy to hardware screen
scrh_fg = _CopyImage(scr_fg, 33)
'_FreeImage scr_fg 'and free software screen from memory

'set image destination to main screen
_Dest 0
If RAMtype$ = "G" Then
_DisplayOrder _Hardware 'do not even render the software layer, just the hardware one.
End If
t = Timer: FRMS = 0
x = imgW \ 4
Do 'main p9rogram loop
'_putimage knows these are hardware screens, so destination of 0 is taken as hardware layer
If RAMtype$ = "C" Then
Cls 'this is needed, otherwise some blending occurs
_PutImage , scr_bg
_PutImage (x, y), scr_fg
End If
If RAMtype$ = "G" Then
_PutImage , scrh_bg
_PutImage (x, y), scrh_fg
End If
'just some input processing
k = _KeyHit
If k = 27 Then Exit Do
Select Case k
Case Asc("`"): EnforceFPS = 60: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("1"): EnforceFPS = 90: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("2"): EnforceFPS = 120: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("3"): EnforceFPS = 144: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("4"): EnforceFPS = 165: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("5"): EnforceFPS = 120 * 2: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("6"): EnforceFPS = 120 * 3: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("7"): EnforceFPS = 120 * 4: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("8"): EnforceFPS = 120 * 5: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("9"): EnforceFPS = 120 * 6: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("0"): EnforceFPS = 120 * 7: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("-"): EnforceFPS = 120 * 8: AutoMode = 1: t = Timer: FRMS = 0
Case Asc("="): EnforceFPS = 120 * 9: AutoMode = 1: t = Timer: FRMS = 0
End Select

If AutoMode = 1 Then
If toggledirec = 0 Then k = Asc("d")
If toggledirec = -1 Then k = Asc("a")
End If
FRMS = FRMS + 1

Select Case k
Case Asc("w"): y = y - 1
Case Asc("a"): x = x - 1
Case Asc("s"): y = y + 1
Case Asc("d"): x = x + 1
'Case Asc("d"): x = x + 1 'commented out duplicate line BY STEVE
End Select

'addition of arrow keys for movement BY STEVE
If _KeyDown(18432) Then y = y - 1: If y < 0 Then y = _Height
If _KeyDown(20480) Then y = y + 1: If y > _Height Then y = 0
If _KeyDown(19200) Then x = x - 1: If x < 0 Then x = _Width
If _KeyDown(19712) Then x = x + 1: If x > _Width Then x = 0
'end of all changes BY STEVE


If x > imgW Then toggledirec = Not toggledirec: _Title Str$(Int(FRMS / (Timer - t + .001))) + " FPS"
If x = 0 Then toggledirec = Not toggledirec

_Display 'render image after changes
_Limit EnforceFPS 'we're doing all this at 480 cycles/second
Loop
System

Sub JuPr
'Color _RGBA(108, 107, 216, 55 + 200), _RGBA32(95, 125, 195,0)
Color _RGBA(2, 2, 2, 55 + 200), _RGBA32(95, 125, 195, 0)
Offs = 8
_PrintString (Offs, 16 * 1 + 3), "'Judas Priest - Some Heads Are Gonna Roll' Lyrics"
_PrintString (Offs, 16 * 2 + 3), ""
_PrintString (Offs, 16 * 3 + 3), UCase$("You can look to the left and look to the right")
_PrintString (Offs, 16 * 4 + 3), UCase$("But you will live in danger tonight ")
_PrintString (Offs, 16 * 5 + 3), UCase$("When the enemy comes, he will never be heard ")
_PrintString (Offs, 16 * 6 + 3), UCase$("He'll blow your mind and not say a word ")
_PrintString (Offs, 16 * 7 + 3), ""
_PrintString (Offs, 16 * 8 + 3), UCase$("Blinding lights ")
_PrintString (Offs, 16 * 9 + 3), UCase$("Flashing colours ")
_PrintString (Offs, 16 * 10 + 3), UCase$("Sleepless nights ")
_PrintString (Offs, 16 * 11 + 3), UCase$("If the man with the power can't keep it under control")
_PrintString (Offs, 16 * 12 + 3), ""
_PrintString (Offs, 16 * 13 + 3), UCase$("Some heads are gonna roll")
_PrintString (Offs, 16 * 14 + 3), ""
_PrintString (Offs, 16 * 15 + 3), UCase$("The power-mad freaks who are ruling the earth")
_PrintString (Offs, 16 * 16 + 3), UCase$("Will show how little they think you're worth ")
_PrintString (Offs, 16 * 17 + 3), UCase$("With animal lust they'll devour your life ")
_PrintString (Offs, 16 * 18 + 3), UCase$("And slice your world to bits like a knife ")
_PrintString (Offs, 16 * 19 + 3), ""
_PrintString (Offs, 16 * 20 + 3), UCase$("One last day ")
_PrintString (Offs, 16 * 21 + 3), UCase$("Burning hell fire ")
_PrintString (Offs, 16 * 22 + 3), UCase$("You're blown away ")
_PrintString (Offs, 16 * 23 + 3), UCase$("If the man with the power can't keep it under control")
_PrintString (Offs, 16 * 24 + 3), ""
_PrintString (Offs, 16 * 25 + 3), UCase$("Know what it's like ")
_PrintString (Offs, 16 * 26 + 3), UCase$("When you're taken for granted")
_PrintString (Offs, 16 * 27 + 3), UCase$("There goes your life ")
_PrintString (Offs, 16 * 28 + 3), UCase$("It's so underhanded ")
_PrintString (Offs, 16 * 29 + 3), ""
_PrintString (Offs, 16 * 30 + 3), UCase$("No, no")
End Sub

Now, my little addition here isn't anything substantial -- all I did was add another manual method for moving the screen manually.

For the original, you can use the WASD keys to scroll the screen up and down/left and right. Run this. Try that. See how quickly the screen scrolls for you.

Then, all I did was add input for the arrow keys to be usable to scroll the screen up and down/left and right. Try those. See how quickly the screen scrolls for you.

Anyone notice a difference in the smoothness and performance?

Many people bottleneck themselves into a crawl by limiting interactions to keyboard repeat rate values -- and those aren't consistent across systems. Some guy might have his keyboard repeat at 5 keystrokes per second. Some other guy might have his at 120. For fluid applications, such as scrolling like this, you might be best served by not limiting your response to that repeat rate at all, like what I've done with the arrow keys here.
Reply
#3
I throw in a +1 for both posts. Before hardware acceleration was added to QB, it was difficult to expect much in comparison to Windows API in regard to the speed of which we could drag windows around the screen. Someday I might add the hardware bit to my graphics GUI simulation and get it "up to speed" so to speak. It used mouse drag but also had keyboard motion which _KeyDown speeds up immensely.

Pete
Shoot first and shoot people who ask questions, later.
Reply
#4
> Many people bottleneck themselves into a crawl by limiting interactions...

Oh, this is so, indeed, including myself.
I battle the non-ergonomic and stupidly accepted without thinking interfaces.
In incoming years I intend to add some original (or good-old and forgotten) GUI features.
Scrolling with keys was left simply to have some moving, your keydown is better, but even better are two additional approaches:
- Holding Shift and a mouse/trackpad button;
- Holding a mouse/trackpad button and moving the mouse/finger.

The speed (as I remember from my GUI Dirwlaker) is hundreds of calls per second which is enough for the ultimate 240/480Hz scenarios. ThinkPads X270/A285/L490 are great in that regard (the three buttons and the trackpad form a duo serving well, yet, the left hand using the keys and right using the mouse is most ergonomic still since the wrists are resting on the desk.

Another usage case of HARDWARE scroll is for POPUPs - those sliding windows either from right-to-left or top-down or down-up waiting in the wings, many times a help window (or some finishing task) is to be quickly (at several hundreds frames) slid. I hate showing window out of nowhere - it stresses the eyes. Such simple things when mounting make the GUIs tiresome, hee-hee, tearsome also.
"He learns not to learn and reverts to what the masses pass by."
Reply




Users browsing this thread: 1 Guest(s)