|Subject:||Re: [Discuss-gnuradio] gr::buffer::allocate_buffer: warning|
|Date:||Tue, 21 Apr 2015 20:33:07 +0200|
|User-agent:||Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0|
ok, you asked for this :D
So, GNU Radio's buffers look a lot like real circular buffers to the blocks using them:
For example, assume your buffer between source block A and sink block B is large enough to store exactly 10000 of your items:
Now, A has produced 9000 items, of which B has already consumed 8000. Your buffer thus looks like this:
- - - - - - - - R W -
With R being the current position of the read pointer, i.e. the address of the first input item of the next B::work() call,
and W being the write pointer, i.e. the address of the first output_item on the next A::work() call.
Each "- " (or "R " or "W ") is 1000 items worth of storage.
Now, we can agree that in this buffer, there are thousand items that must not be overwritten by the next A::work call, and 9000 items space for new items.
What GNU Radio does is employ memory mapping magic to allow A to simply write contigously the next 9000 items; to the process, the memory looks like this:
- - - - - - - - R W -|- - - - - - - - R W -
Notice that the second half is really just a transparent image of the first, being inserted there by the memory control unit of your CPU.
Now, that is awesome on so many levels:
* it allows developers to always write their applications like the in- and output was just linear in memory, no matter where in their buffer they are
* it allows full usage of the buffer, without having extra space allocated
Of course, this has an architectural downside:
On any fully-fledged general purpose CPU platform I know, you can only do this with pages; a page is simply the smallest amount of memory you can tell your memory management unit to map somewhere.
On Linux, these pages are generally 4KB. That's usually a bit handy, because it's a power of two bytes, which means that the typical item sizes (1B for a byte/char, 2B for a short, 4B for a float or int, and 8B for a std::complex<float> == gr_complex) fit well here, but not so cool if your item's size is not a divider of 2**12. In that case, the scheduler has no chance but to find the smallest common multiple of 4096 and your item size.
On 04/21/2015 08:04 PM, Anderson, Douglas J. wrote:
|[Prev in Thread]||Current Thread||[Next in Thread]|