Our project want to use PhysX binary file format, but I founded that the alignment of memory block for deserializing is 128 Byte(PX_SERIAL_FILE_ALIGN).
Our asset system prefer a 16 Byte alignment, so I want to know the purpose of setting PX_SERIAL_FILE_ALIGN to 128 and to decide if I can change it to 16.

Some features like PxArticulation depend on alignment greater than 16 so it would probably be unsafe to be 16-byte aligned if you were using PxArticulation. There may be other portions of PhysX that require non 16-byte alignment but that is the one that I’m aware of.

So if we may use PxArticulation to create something like ragdolls, change the alignment to 16Byte will invoke errors. And even we don’t use PxArticulation, it also can be very risky, right?
I think we should change our system to fit the 128Byte alignment.

Thanks for your reply kstorey!

Hi, kstorey

I checked PhysX’s source code about PxArtivulation and where PX_SERIAL_FILE_ALIGN is used, but I can not find the case which the 128Byte alignment should be kept. It is very helpful if you can give me some example of this.

We are using PhysX but only on CPU. If the alignment case is about GPU or for some platform like PlayStation3, it will be all right.

Articulations are aligned to 128 bytes so we can use a single pointer to either a rigid body or articulation in constraints, with the lower bits of the articulation pointer tell us which link within the articulation the constraint references.

As an example, here in PxsIslandManagerTypes.h:

\brief An index describing how to access body0

\note If body0 is a dynamic (eBODY) rigid body then solverBody0 is an index into PxsIslandObjects::bodies.
\note If body0 is a kinematic (eKINEMATIC) rigid body then solverBody0 is an index into PxsIslandManager::getActiveKinematics.

\note If body0 is a static (eWORLD) then solverBody0 is PX_MAX_U32 or PX_MAX_U64, depending on the platform being 32- or 64-bit.

\note If body0 is an articulation then the articulation is found directly from Dy::getArticulation(articulation0)
	PxsNodeType					solverBody0;
	Dy::ArticulationLinkHandle	articulation0;

We don’t make use that of that PX_SERIAL_FILE_ALIGN within the rest of the SDK so searching for it won’t show up where the restrictions originate from. However, this is a requirement that it would be risky to try and disable - it may work if you don’t use some features but for the amount of risk and effort required to switch to 16-byte aligned serial buffers, you could have just as easily allocated a 128-byte aligned buffer and not incur any risk of random failures.

Allocating 128 byte aligned pointer is fairly straightforward. Just allocate more data than you need and get an aligned pointer within the range of memory you allocated.

Releasing that buffer can be a little tricky. What I would suggest is as follows:

When allocating the memory, do something like this:

void* allocate128Aligned(size_t size)

size_t pointer = reinterpret_cast<size_t>(malloc(size + 256)); //allocate an extra 256 bytes for padding

size_t* ptr = reinterpret_cast<size_t*>((pointer + 128) & (~127)); //pad to the next 128 byte alignment

*(ptr - 1) = pointer; //Store the original pointer you allocated in the preceding memory address so you can look it up during release to get the originally-allocated pointer.

return ptr;

In release, you do the following:

void Free128(void* address)

size_t baseAddress = (reinterpret_cast<size_t>(address) - 1); //Retrieve the original pointer from address - 1

The above code wastes a bit of memory - you could allocate less and align using (pointer+127)&(~127) but then you could not safely ensure there was space to store the original pointer and, without that, deallocating could be tricky.

I checked the source code about PxArticulation and found that the lower 3 bits are for links. So the memory address for articulation must be aligned to at least 64 bytes.

Thanks for your answer and the sample of memory allocation.