File Exchange

image thumbnail

circVBuf

version 1.6.0.0 (91 KB) by Jens Henrik Göbbert
circular vector buffer (constant+fast performance, double buffered)

4 Downloads

Updated 30 Jun 2014

View License

circVBuf class defines a circular double buffered vector buffer
* newest vector has the highest index
* oldest vector has the lowest index
* append adds new vectors at the 'right side' of the buffer
* current buffer always accessable as a complete single subarray buf(fst:lst)

specials:
* any matrix operations at any time possible !
* time required for appending is independent on buffer status !
* index 'new' indicates the start of last appended vectors

The main idea of this circular buffer is constant performance (=> double buffering) and avoiding copy operations when using the buffer in a program.
Check the screenshot to see, that this circular buffer has advantages if the buffer is large, but the size of data to append each time is small as the performance of circVBuf does NOT depend on the buffer size, compared to a simple copy buffer.

The double buffering garanties a predictive time for an append depending on the data to append in any situation. In future this class shall give you a choice for double buffering yes or no - things will speedup, if you do not need the garantied time.

example 1
create a circular vector buffer
bufferSz = 1000;
vectorLen= 7;
cvbuf = circVBuf(int64(bufferSz),int64(vectorLen));

example 2
fill buffer with 99 vectors
vecs = zeros(99,vectorLen,'double');
cvbuf.append(vecs);

example 3
loop over lastly appended vectors of a circVBuf:
new = cvbuf.new;
lst = cvbuf.lst;
for ix=new:lst
vec(:) = cvbuf.raw(:,ix);
end

example 4
direct array operation on lastly appended vectors in the buffer (no copy => fast)
new = cvbuf.new;
lst = cvbuf.lst;
mean = mean(cvbuf.raw(3:7,new:lst));

example 5
MATLAB makes copies of arrays only when the data referred to changes (this is called copy on write or lazy copying). As long as the first index is fixed, the following should not result in a copy and should be of same speed as example 4 even for large arrays:
new = cvbuf.new;
lst = cvbuf.lst;
vbuf3 = cvbuf.raw(3,new:lst);
mean(vbuf3);

For comparison more append-types are added (appendType is argument of constructor):
0: default (double buffering, move fst/lst with each append)
1: simply copy always all -- buf = [buf(2:end,:); vecs(:,:)] (fst == 1 always)
2: copy all into old buffer, if end of buffer reached (fst == 1 always)
3: copy-all into new buffer, if end of buffer reached (fst == 1 always)

Please comment concerning performance and other issues.
Code generation should work.

Comments and Ratings (5)

Tago

Do not work in 2018b, following the examples it lead to
Index in position 2 exceeds array bounds
(must not exceed 7).

vec(:) = cvbuf.raw(:,ix);

Abel Brown

is it possible to resize at runtime?

'a' takes twice as much time in matlab 2014a as 'b' for appendType==1 is fixed in 0.9.3

Question from the author:

a) obj.raw = [ obj.raw(2:end,:); vec(:) ]
b) raw = [ raw(2:end,:); vec(:) ]

'a' takes twice as much time in matlab 2014a as 'b':

It seems to me as if matlab makes an internal copy when using 'a', which it does not when using 'b'. But in OO programming I cannot avoid 'a' and switch to 'b'.

Any idea how to speedup 'a'?

Updates

1.6.0.0

setup() sets the function pointer 'append' -> switching appendType only requires since now a different construction call and no different 'append' call anymore.

1.5.0.0

1) twice as fast for appendType==1 (thanks to Geoff Hayes)
2) fixed the legend of plot_circVBuf_speedtest.m (thanks to Geoff Hayes)

1.4.0.0

For comparison more append-types are added and the speedtest has been extended
0: default
1: simply copy always all
2: copy all into old buffer, if end of buffer reached
3: copy-all into new buffer, if end of buffer reached

1.3.0.0

[... as the performance of circVBuf does NOT depend on the buffer size, compared to a simple copy buffer.]

1.2.0.0

added screenshot and speedtest

1.1.0.0

added example 5 to the description

MATLAB Release Compatibility
Created with R2014a
Compatible with any release
Platform Compatibility
Windows macOS Linux