Jed, Seems ok to me. Feel free to update PETSc. (But I think PETSc style would detect that your PETSC_ALIGN() macro would be called PetscMemAlign() or something, we only use caps for macros that are fixed values, not for macros that like functions.) Thanks for thinking about this, Barry On Nov 16, 2009, at 4:11 AM, Jed Brown wrote:
Barry Smith wrote:
Agreed this would be a good option to have. The question is how to do it without having a morass of nasty nested if-defs. Note that portably getting alignment out of malloc() alone is already ugly and not as simple a code as I would like.
To simplify things we could always require 16 byte alignment everywhere? But is that a desirable?
I doubt it's harmful, I don't think I understand where the nested ifdefs come in. The required alignment only needs to be stated in one place, I have something like the following in one of my projects.
/* current */ #define PetscMalloc3(m1,t1,r1,m2,t2,r2,m3,t3,r3) \ (PetscMalloc((m1)*sizeof(t1)+(m2)*sizeof(t2)+ (m3)*sizeof(t3),r1) \ || (*(r2) = (t2*) (*(r1)+m1), \ *(r3) = (t3*)(*(r2)+m2),0))
/* aligned */ #define PetscMalloc3(m1,t1,r1,m2,t2,r2,m3,t3,r3) \ (PetscMalloc((m1)*sizeof(t1)+(m2)*sizeof(t2)+ (m3)*sizeof(t3)+2*(PETSC_MEMALIGN-1),r1) \ || (*(r2) = (t2*)PETSC_ALIGN(*(r1)+m1), \ *(r3) = (t3*)PETSC_ALIGN(*(r2)+m2),0))
#define PETSC_ALIGN(p) PetscNextAligned((uintptr_t) (p),PETSC_MEMALIGN-1)
static inline void *PetscNextAligned(uintptr_t base,uintptr_t mask) {return (void*)((base + mask) & ~mask);}
Note that this is a no-op if PETSC_MEMALIGN=1 and thus compiles to exactly what we have now.
Jed