PDA

View Full Version : Fast bit doubling, how?



CuriousOne
- 27th September 2022, 17:08
Hello. Most likely, I asked this before, but can't find the topic :(

The top is the original variable, represented in bit form.
The bottom is desired result. It is just each bit doubled, so final result occupies two bits.



11011101


11110011 11110011


Technically, I've done it a way that each bit of input variable is read, then written into another variables two times, next to each other.
This indeed works, but it is very slow. Is there any other method of achieving this?
I need this for font scaling..

HenrikOlsson
- 27th September 2022, 19:01
Define very slow so we have something to compare against.



outvar.0 = invar.0
outvar.1 = invar.0
outvar.2 = invar.1
outvar.3 = invar.1
outvar.4 = invar.2
outvar.5 = invar.2
outvar.6 = invar.3
outvar.7 = invar.3
outvar.8 = invar.4
outvar.9 = invar.4
outvar.10 = invar.5
outvar.11 = invar.5
outvar.12 = invar.6
outvar.13 = invar.6
outvar.14 = invar.7
outvar.15 = invar.7

The above brute force version takes <4.1us @64MHz. Extrapolating to 4MHz = 66us or 15150 times per second.
I don't think I can come up with a faster PBP version, perhaps some ASM guru can but knowing you you don't want that :-)

CuriousOne
- 27th September 2022, 20:44
Well, screen buffer if 128x64 pixels. That's 16x64 bytes, that's 1KB.
Since I can't keep it in memory, it is "rebuilt" on the fly, each time display updates.
I'm not doing any smooth scrolling or FX, so 5 fps should be enough.

The routine works as follows - text is read from array letter by letter, appropriate location of EEPROM is read, to get font data, which is then sent to display. With "my" method, it takes approximately 1.2 seconds to redraw whole display. I'll check tomorrow this method and post back about the speed.

HenrikOlsson
- 28th September 2022, 06:04
Well, if the screenbuffer is 1kB it means that you're converting 512 bytes to "double bytes". Even at 4MHz that conversion can be done 30 times/second.
If the refreshing the screen takes 1.2s (!) this "bit doubling" is only ~3% of that time. The bottleneck is elsewhere.

CuriousOne
- 28th September 2022, 06:22
Yes, it is in my code, because I was doing manual reading of bits :D
will fix it today :)

tumbleweed
- 28th September 2022, 12:16
Even though it looks longer, this should end up almost twice as fast...


outvar = 0
if (invar.0) then
outvar.0 = 1
outvar.1 = 1
endif
if (invar.1) then
outvar.2 = 1
outvar.3 = 1
endif
if (invar.2) then
outvar.4 = 1
outvar.5 = 1
endif
if (invar.3) then
outvar.6 = 1
outvar.7 = 1
endif
if (invar.4) then
outvar.8 = 1
outvar.9 = 1
endif
if (invar.5) then
outvar.10 = 1
outvar.11 = 1
endif
if (invar.6) then
outvar.12 = 1
outvar.13 = 1
endif
if (invar.7) then
outvar.14 = 1
outvar.15 = 1
endif

Ioannis
- 28th September 2022, 13:14
I think #2 is faster.

Ioannis

tumbleweed
- 28th September 2022, 14:20
It can depend on the device and where the variables end up, but here's a contrast of the two methods (post #2, post #6)


invar #2 #6
$00 64 34
$01 64 36
$55 64 42
$FF 64 50

That's for an 18F26K22. Results are in instruction cycles.
Post #2 has the "advantage" of always taking 64 cycles, but #6 is always faster.

Ioannis
- 28th September 2022, 15:10
Impressive!

Thanks,
Ioannis