Re: Memory alignment
On Fri, Feb 03, 2017 at 04:07:25PM +0100, Boudewijn Dijkstra wrote: > Op Sat, 28 Jan 2017 06:26:16 +0100 schreef Damian McGuckin > : > > What is the recommended most portable way to force memory alignment for > > a datum of any type, assuming one has a pointer say > > > > char *x > > > > I currently use something like > > > > char *xany = aligntonext(x, sizeof(long)) > > > > where I use my own function 'aligntionext' which is defined below and I > > also assume that a 'long' will be the natural word-size of the machine > > and that any datum things just needs to align to this boundary. That > > said, if the second argument is say 4k, the function will align its > > result to a 4k boundary. > > > > I was wondering if there is an optimal, better, more acceptable, or more > > portable, way. > > > > Easy and very portable: > > void * > aligntonext(void *x, size_t size) > { > return (void *)uintptr_t)x + size - 1u) / size) * size); > } > > Whether it is optimal depends on compiler optimization. Isn't this stuff macros are made of: # define aligntonext(ptr, size) \ ((void*)uintptr_t)(ptr) + (size) - 1u) / (size)) * (size))) Or # define aligntonext(ptr, bits) \ ((void*)uintptr_t)(ptr) + (1<<(bits)) - 1u) >> (bits)) << (bits))) Note that the second argument is evaluated three times in both variants... -- / Raimo Niskanen, Erlang/OTP, Ericsson AB
Re: Memory alignment
Op Sat, 28 Jan 2017 06:26:16 +0100 schreef Damian McGuckin : What is the recommended most portable way to force memory alignment for a datum of any type, assuming one has a pointer say char *x I currently use something like char *xany = aligntonext(x, sizeof(long)) where I use my own function 'aligntionext' which is defined below and I also assume that a 'long' will be the natural word-size of the machine and that any datum things just needs to align to this boundary. That said, if the second argument is say 4k, the function will align its result to a 4k boundary. I was wondering if there is an optimal, better, more acceptable, or more portable, way. Easy and very portable: void * aligntonext(void *x, size_t size) { return (void *)uintptr_t)x + size - 1u) / size) * size); } Whether it is optimal depends on compiler optimization. -- Gemaakt met Opera's e-mailprogramma: http://www.opera.com/mail/
Re: Memory alignment
On Sat, 28 Jan 2017, Kyoung Jae Seo wrote: Maybe posix_memalign(3) is API you are looking for. No. This allocates memory. I already have the buffer. I am trying to use space within it. Regards - Damian Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037 Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here Views & opinions here are mine and not those of any past or present employer
Re: Memory alignment
Hi. On Sat, Jan 28, 2017 at 04:26:16PM +1100, Damian McGuckin wrote: > What is the recommended most portable way to force memory alignment for a > datum of any type, assuming one has a pointer say > > char *x > > I currently use something like > > char *xany = aligntonext(x, sizeof(long)) > > where I use my own function 'aligntionext' which is defined below and I also > assume that a 'long' will be the natural word-size of the machine and that > any datum things just needs to align to this boundary. That said, if the > second argument is say 4k, the function will align its result to a 4k > boundary. > > I was wondering if there is an optimal, better, more acceptable, or more > portable, way. Maybe posix_memalign(3) is API you are looking for.
Memory alignment
What is the recommended most portable way to force memory alignment for a datum of any type, assuming one has a pointer say char *x I currently use something like char *xany = aligntonext(x, sizeof(long)) where I use my own function 'aligntionext' which is defined below and I also assume that a 'long' will be the natural word-size of the machine and that any datum things just needs to align to this boundary. That said, if the second argument is say 4k, the function will align its result to a 4k boundary. I was wondering if there is an optimal, better, more acceptable, or more portable, way. I tried to look in malloc.c and realized that now there are 6 versions in /usr/src. After reading them all, my head started spinning. Is there was an easy answer? Regards - Damian Source of aligntonext --> #include #include #include /* * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetTable */ static unsigned int numberofsetbits(unsigned int i) { i = i - ((i >> 1) & 0x); i = (i & 0x) + ((i >> 2) & 0x); return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; } /* * adjust pointer such that is aligned to a given number of bytes */ void * aligntonext(void *x, size_t size) { unsigned int bits = numberofsetbits((unsigned int) (size - 1)); unsigned long long p = (unsigned long long) x; assert(size == (size_t)(1 << bits)); p += (1 << bits) - 1; p >>= bits; p <<= bits; return (void *) p; } Regards - Damian Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037 Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here Views & opinions here are mine and not those of any past or present employer