08-28-2022, 01:26 AM
I was curious about if drawing with _mem commands would improve performance. So, I used you test as inspiration for my own test.
I'm using Bresenham Circle drawing algorithm, just as you had, but I get very different results, from your implementation. Most slower, except while using 1 byte per pixel.
Overall my times are pretty sad. I do have a slow computer.
Can one of you guys point out my inefficiency? Perhaps I'm doing something unnesessary or dumb?
I'm using Bresenham Circle drawing algorithm, just as you had, but I get very different results, from your implementation. Most slower, except while using 1 byte per pixel.
- Optimization flag is set.
- I tried using _SHL in place of multiplying by 2,4,8 and it slowed it down, which is surprising, but I guess the compiler is doing a better job of multiplying.
- I did not implement clipping in the MEM rountines just assuming it would just slow down the test.
- I've noticed that Line command seems to be faster at drawing a horizontal line then memfill with a unsigned long. (Suprising!)
Overall my times are pretty sad. I do have a slow computer.
- Bresenham normal - 12.68 sec
- Bresenham MEM 1bbp - .99 sec
- Bresenham MEM 4bbp - 16.09 sec
Can one of you guys point out my inefficiency? Perhaps I'm doing something unnesessary or dumb?
Code: (Select All)
_TITLE "Fast Circle Test"
DIM AS LONG scrn
DIM AS LONG count
DIM AS SINGLE t0, t1
DIM AS STRING en
TYPE tRESULTS
AS SINGLE time
AS STRING test
END TYPE
DIM AS tRESULTS res(10)
scrn = _NEWIMAGE(800, 500, 256)
SCREEN scrn
CONST iterations = 640000
'____________________________________________________________________________________________________________________________________
res(0).test = "Bresenham Normal Test"
LOCATE 20, 1
PRINT res(0).test
INPUT "Press Enter to start ..."; en
count = 0
t0 = TIMER
DO
CircleBresenham INT(RND * 800), INT(RND * 500), 30, INT(RND * 255)
count = count + 1
LOOP WHILE count < iterations
t1 = TIMER
res(0).time = t1 - t0
'____________________________________________________________________________________________________________________________________
res(1).test = "Bresenham MEM 1bpp (no clip)"
LOCATE 20, 1
PRINT res(1).test
INPUT "Press Enter to start ..."; en
count = 0
t0 = TIMER
DIM AS _MEM scr
scr = _MEMIMAGE(scrn)
DO
CircleBresenham1bpp scr, 30 + INT(RND * 740), 30 + INT(RND * 440), 30, INT(RND * 255)
count = count + 1
LOOP WHILE count < iterations
_MEMFREE scr
t1 = TIMER
res(1).time = t1 - t0
'____________________________________________________________________________________________________________________________________
res(2).test = "Bresenham MEM 4bpp (no clip)"
LOCATE 20, 1
PRINT res(2).test
INPUT "Press Enter to start ..."; en
_TITLE "Fast Circle Test"
scrn = _NEWIMAGE(800, 500, 32)
SCREEN scrn
LOCATE 20, 1
count = 0
t0 = TIMER
scr = _MEMIMAGE(scrn)
DO
CircleBresenham4bpp scr, 30 + INT(RND * 740), 30 + INT(RND * 440), 30, _RGB32(INT(RND * 255), INT(RND * 255), INT(RND * 255))
count = count + 1
LOOP WHILE count < iterations
_MEMFREE scr
t1 = TIMER
res(2).time = t1 - t0
'____________________________________________________________________________________________________________________________________
PRINT "Circle count:"; iterations
FOR count = 0 TO 2
PRINT res(count).test; " Time:"; res(count).time
NEXT
'____________________________________________________________________________________________________________________________________
SUB CircleBresenham (xc AS LONG, yc AS LONG, r AS LONG, c AS LONG)
DIM AS LONG e, x, y, w
DIM AS LONG l0, l1
w = _WIDTH(0) * 4
x = r
y = 0
e = 0
$CHECKING:OFF
DO
l0 = x * 2
l1 = y * 2
LINE (xc - x, yc - y)-(xc - x + l0, yc - y), c
LINE (xc - x, yc + y)-(xc - x + l0, yc + y), c
LINE (xc - y, yc - x)-(xc - y + l1, yc - x), c
LINE (xc - y, yc + x)-(xc - y + l1, yc + x), c
IF x <= y THEN EXIT DO
e = e + y * 2 + 1
y = y + 1
IF e > x THEN
e = e + 1 - x * 2
x = x - 1
END IF
LOOP
$CHECKING:ON
END SUB
SUB CircleBresenham1bpp (scr AS _MEM, xc AS LONG, yc AS LONG, r AS LONG, c AS _UNSIGNED _BYTE)
DIM AS LONG e, x, y, w
DIM AS LONG xof0, xof1, xof2, xof3, l0, l1
DIM AS LONG yof0, yof1, yof2, yof3
DIM AS LONG xq0, yq0, xq1, yq1, xq2, yq2, xq3, yq3
w = _WIDTH(0)
x = r
y = 0
e = 0
$CHECKING:OFF
DO
l0 = x * 2
l1 = y * 2
xq0 = xc - x
yq0 = yc - y
xof0 = xq0
yof0 = yq0 * w
_MEMFILL scr, scr.OFFSET + xof0 + yof0, l0, c AS _UNSIGNED _BYTE
xq1 = xc - x
yq1 = yc + y
xof1 = xq1
yof1 = yq1 * w
_MEMFILL scr, scr.OFFSET + xof1 + yof1, l0, c AS _UNSIGNED _BYTE
xq2 = xc - y
yq2 = yc - x
xof2 = xq2
yof2 = yq2 * w
_MEMFILL scr, scr.OFFSET + xof2 + yof2, l1, c AS _UNSIGNED _BYTE
xq3 = xc - y
yq3 = yc + x
xof3 = xq3
yof3 = yq3 * w
_MEMFILL scr, scr.OFFSET + xof3 + yof3, l1, c AS _UNSIGNED _BYTE
IF x <= y THEN EXIT DO
e = e + y * 2 + 1
y = y + 1
IF e > x THEN
e = e + 1 - x * 2
x = x - 1
END IF
LOOP
$CHECKING:ON
END SUB
SUB CircleBresenham4bpp (scr AS _MEM, xc AS LONG, yc AS LONG, r AS LONG, c AS LONG)
DIM AS LONG e, x, y, w
DIM AS LONG xof0, xof1, xof2, xof3, l0, l1
DIM AS LONG yof0, yof1, yof2, yof3
DIM AS LONG xq0, yq0, xq1, yq1, xq2, yq2, xq3, yq3
w = _WIDTH(0) * 4
x = r
y = 0
e = 0
$CHECKING:OFF
DO
l0 = x * 8
l1 = y * 8
xq0 = xc - x
yq0 = yc - y
xof0 = xq0 * 4
yof0 = yq0 * w
_MEMFILL scr, scr.OFFSET + xof0 + yof0, l0, c AS _UNSIGNED LONG
xq1 = xc - x
yq1 = yc + y
xof1 = xq1 * 4
yof1 = yq1 * w
_MEMFILL scr, scr.OFFSET + xof1 + yof1, l0, c AS _UNSIGNED LONG
xq2 = xc - y
yq2 = yc - x
xof2 = xq2 * 4
yof2 = yq2 * w
_MEMFILL scr, scr.OFFSET + xof2 + yof2, l1, c AS _UNSIGNED LONG
xq3 = xc - y
yq3 = yc + x
xof3 = xq3 * 4
yof3 = yq3 * w
_MEMFILL scr, scr.OFFSET + xof3 + yof3, l1, c AS _UNSIGNED LONG
IF x <= y THEN EXIT DO
e = e + y * 2 + 1
y = y + 1
IF e > x THEN
e = e + 1 - x * 2
x = x - 1
END IF
LOOP
$CHECKING:ON
END SUB