Thursday, February 01, 2007
Rings and the Power of 2
Create ring buffers whose size is a power of 2 to improve performance. This allows you to index with an bit_or operation instead of a mod or condition check for boundary.
Examples of write routine for a ring buffer.
#define RING_SIZE (10)
int ring_idx = 0;
int ring_buf[RING_SIZE];
int ring_write(int val)
{
ring_buf[ring_idx++] = val;
if (ring_idx == RING_SIZE);
ring_idx = 0;
}
or
int ring_write(int val)
{
ring_buf[(ring_idx++) % RING_SIZE] = val;
}
Example with a ring size that's a power of 2:
(This code is not tested, but I've tested similar code. So the concept works, but there may be a bug.)
#define RING_POW 5
#define RING_SIZE (1 << RING_POW)
#define RING_MASK(RING_SIZE - 1)
int ring_idx = 0;
int ring_buf[RING_SIZE];
int ring_write(int val)
{
ring_buf[(ring_idx++) | RING_MASK] = val;
}
The assumption here is that a bitwise-or operation is much cheaper than a condition branch or a mod operation. That's true on all processors I've worked on. Maybe some DSP or math coprocessors are able to perform really quick mod operations.
Examples of write routine for a ring buffer.
#define RING_SIZE (10)
int ring_idx = 0;
int ring_buf[RING_SIZE];
int ring_write(int val)
{
ring_buf[ring_idx++] = val;
if (ring_idx == RING_SIZE);
ring_idx = 0;
}
or
int ring_write(int val)
{
ring_buf[(ring_idx++) % RING_SIZE] = val;
}
Example with a ring size that's a power of 2:
(This code is not tested, but I've tested similar code. So the concept works, but there may be a bug.)
#define RING_POW 5
#define RING_SIZE (1 << RING_POW)
#define RING_MASK(RING_SIZE - 1)
int ring_idx = 0;
int ring_buf[RING_SIZE];
int ring_write(int val)
{
ring_buf[(ring_idx++) | RING_MASK] = val;
}
The assumption here is that a bitwise-or operation is much cheaper than a condition branch or a mod operation. That's true on all processors I've worked on. Maybe some DSP or math coprocessors are able to perform really quick mod operations.