470,849 Members | 941 Online

# Compute buffer size at compile-time

Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

I came up with: (BS stands for BUFFER_SIZE)

(BS & ~15) + ((BS&15 != 0) << 4)

which can be written in a simpler way:

((BS-1) & ~15) + 16

Although there might be a problem if BS is an int and 0.
I think 0-1 is well-defined if BS is an unsigned int?

I also toyed with the idea of returning the next power of 2:

31 -> 32
32 -> 32
33 -> 64
48 -> 64
64 -> 64
65 -> 128

but I couldn't figure out how to compute it at compile-time elegantly.
(I need a loop which I could completely unroll... ugly.)

Regards.
Apr 30 '06 #1
6 2357 Spoon <none> wrote:
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

#define N (BS / 16) * 16 + 16 ?
--
:wq
^X^Cy^K^X^C^C^C^C
Apr 30 '06 #2
Ico wrote:
Spoon <none> wrote:
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

#define N (BS / 16) * 16 + 16 ?

Be careful of those boundary cases. If BS is divisible
by 16, the above formula adds an extra 16 instead of just
leaving it alone.

#define N ((BS + 15) & ~15)

More generally,

#define ROUNDUP(min,chunk) \
(((min) + (chunk) - 1) / (chunk) * (chunk))

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 30 '06 #3
Ico <us****@zevv.nl> wrote:
Spoon <none> wrote:
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

#define N (BS / 16) * 16 + 16 ?

question.

--
:wq
^X^Cy^K^X^C^C^C^C
Apr 30 '06 #4

"Spoon" <none> wrote in message
news:44**********************@news.free.fr...
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

That returns one if N is a multiple of sixteen and over 1234. Don't you
want it to return one if N is a multiple of sixteen below 1234 and return
one for all values over 1234? I think you want an logical or, '||', instead
of a logical and, '&&'.

That would be this:
(N >= 1234) || ((N % 16) == 0)

If your compiler uses two's complement (most do), that simplifies to this
(for unsigned values):

(N >= 1234) || (!(N&0x0F))

The value '1234' isn't expressed in binary in a manner which could eliminate
the comparison (i.e., all bits set).

(BS & ~15) + ((BS&15 != 0) << 4)
Except for zero which returns 0, this returns the multiple of sixteen larger
than the current value. I don't think you wanted that.
((BS-1) & ~15) + 16

Again, except for zero which returns 0, this returns the multiple of sixteen
larger than the current value.
HTH,

Rod Pemberton
May 1 '06 #5

"Eric Sosman" <es*****@acm-dot-org.invalid> wrote in message
news:3e********************@comcast.com...
Ico wrote:
Spoon <none> wrote:
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

#define N (BS / 16) * 16 + 16 ?

Be careful of those boundary cases. If BS is divisible
by 16, the above formula adds an extra 16 instead of just
leaving it alone.

#define N ((BS + 15) & ~15)

More generally,

#define ROUNDUP(min,chunk) \
(((min) + (chunk) - 1) / (chunk) * (chunk))

While you corrected Spoon's post, you didn't realize his or two of the OP's
calculations don't compute "N >= 1234 && N % 16 == 0" properly.
Rod Pemberton
May 1 '06 #6
Rod Pemberton wrote:
"Eric Sosman" <es*****@acm-dot-org.invalid> wrote in message
news:3e********************@comcast.com...
Ico wrote:

Spoon <none> wrote:
Hello,

Consider:

#define BUFFER_SIZE 1234 /* or some other value */
uint8_t buffer[BUFFER_SIZE];
int do_stuff(uint8_t *buf);

where do_stuff() does something with each octet in the buffer.

Assume I've come up with do_stuff_2() similar to do_stuff() but
that works with 16 octets at a time.

I need to compute N at compile time
such that N >= 1234 && N % 16 == 0

#define N (BS / 16) * 16 + 16 ?

Be careful of those boundary cases. If BS is divisible
by 16, the above formula adds an extra 16 instead of just
leaving it alone.

#define N ((BS + 15) & ~15)

More generally,

#define ROUNDUP(min,chunk) \
(((min) + (chunk) - 1) / (chunk) * (chunk))

While you corrected Spoon's post, you didn't realize his or two of the OP's
calculations don't compute "N >= 1234 && N % 16 == 0" properly.

That expression isn't the result he's trying to compute.
He's trying to find an N such that the above expression will
be true, not to test whether it is true for a given N.

He didn't say so, but I assumed from context that he wants
not just any such N, but the least such N. It was on the basis
of that assumption that I responded -- not to Spoon's post but
to Ico's, by the way.

--
Eric Sosman
es*****@acm-dot-org.invalid
May 1 '06 #7

### This discussion thread is closed

Replies have been disabled for this discussion.

### Similar topics

 1 post views Thread by gaool | last post: by 2 posts views Thread by derek.google | last post: by 2 posts views Thread by William Stacey | last post: by 1 post views Thread by ad | last post: by 2 posts views Thread by Macca | last post: by 7 posts views Thread by toton | last post: by 28 posts views Thread by bwaichu | last post: by 6 posts views Thread by vaidehikedlaya | last post: by 4 posts views Thread by aki | last post: by reply views Thread by martinmercy2001 | last post: by reply views Thread by AlexandraMT | last post: by 1 post views Thread by DANILIN | last post: by reply views Thread by tracyyun | last post: by reply views Thread by sjain6 | last post: by reply views Thread by milkinvl | last post: by reply views Thread by shivajikobardan | last post: by reply views Thread by gglobus | last post: by reply views Thread by Ravipg | last post: by reply views Thread by DJRhino1175 | last post: by