-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom alignment support, progress #11077
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice work, I'm eagerly waiting for the aligned allocator as well :).
Nitpick, I'd like an additional test case with sizeof(T) to make sure it's usable with generics.
c: char | ||
x: float | ||
|
||
MyAlignedGenericType[T] {.align: 32.} = object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a {.align: sizeof(T).} test as well?
Sorry, but this is incorrect. User alignment cannot "superseed" the type
MyAlignedType {.align: 64.} =
someByte: byte
someFloat: float64
doAssert(sizeof(MyAlignedType) == 64)
doAssert(offsetof(MyAlignedType,someFloat) == 8) # <- this will fail Your implementation implicitly sets Apart from this technical detail, I do agree that we need user alignment. But you need to extend your test cases to test the offset values of the object members as well. |
@krux02: Thanks for review. The actual problem that didn't know the difference between computeObjectOffsetsFoldFunction and computePackedObjectOffsetsFoldFunction so I used it blindly. It will not be hard to fix. |
This is related to this medium priority issue opened since 2015 #1930. type Foo = object
x: int
y{.align: 16.}: array[4, float32] |
It would make sense if a compilation error would be risen if the programmer requests a low alignment value, for example 4, but one of the members requires a higher alignment value, for example 8. type
MyType {.align: 4.} = object
member: float64 # <- should be a compilation error Then, the last point is about packed objects with SIMD type members. Normally, when you have a packed object with unaligned members, everything works fine, except that performance might be bad. But for SIMD types this is a bit different. When you have non aligned SIMD types and try to load them, the program might even crash. So maybe it is worth to check if the programmer tries to do that and then raise a compilation error. But I am not sure if it is worth to implement the error checking right now, as the programmer will notice the error. It is just that the error could be prevented from the Nim compiler. |
@krux02 Regarding packed pragma. |
Regarding packed object with SIMD type members. I think it is best to introduce another flag for hard constraint alignment that would be used on SIMD types. Then I would raise a compilation error when somebody tries to pack an object with SIMD type members. This is really the safe way to do it, as you don't need to see what different C compilers do. Pseudocode: type
Vec4f {.align: 16, hardAlign.} = object
data: array[4,float32]
MyType {.packed.} = object
a: byte
v: Vec4f # error packed pragma violates hard alignment constraint of Vec4f (align: 16) |
Seems not to be required anymore now that we have fieldwise alignment annotations. |
align pragma now affects codegen. Align also implied packed, such that bigger alignment increase object size, but smaller alignment decrease it.
Summary of the changes:
size
pragmatfPacked
type flag is superseded by tfUserAligment flag. Effectivelypacked
pragma is equivalent ofalign: 1
pragma now.The feature remains widely undocumented for the main reason: allocator and GC now need to take alignment type information into account to make this feature truly public and useful.