[swift-users] Can I use a tuple to force a certain memory layout?
davesweeris at mac.com
Fri Jul 21 11:16:19 CDT 2017
> On Jul 21, 2017, at 07:55, Johannes Weiß via swift-users <swift-users at swift.org> wrote:
>> On 21 Jul 2017, at 1:45 am, Taylor Swift <kelvin13ma at gmail.com> wrote:
>> Okay, apparently layout is only guaranteed if the reference is to the tuple itself, not a member of the tuple. Don’t know if this is a bug or intended behavior. The above code works when written as
>> var buffers:(VBO:GL.UInt, EBO:GL.UInt) = (0, 0)
>> withUnsafeMutablePointer(to: &buffers)
>> $0.withMemoryRebound(to: UInt32.self, capacity: 2)
>> glGenBuffers(n: 2, buffers: $0)
> this is legal now as you're now observing the whole tuple rather than just one value. That means they're now guaranteed to be in standard C layout.
> In other words, Swift could have the tuple in memory like this
> | VBO | whatever | EBO |
> ^ ^ ^
> | | |
> a b c
> when you now get a pointer to &buffers.VBO, you'll get the pointer 'a' and as you see, you'll not be guaranteed to have EBO right next to it.
> It you however request a pointer to `buffers` as a whole, the Swift compiler will do whatever is necessary to give you a compound view in standard C layout. Ie. it might copy it into
> | VBO | EBO |
> and after the call returns put the VBO and EBO values back where they're supposed to be.
> Does that make sense?
So... It seems to me that shuffling things around like that would have some overhead. What are the performance implications here? Is it just a matter of profiling our code twice -- once with the type defined in Swift and once with it defined in C? I mean presumably the Swift compiler wouldn't interject "stuff" between the elements without a reason, but OTOH having smaller types means that more of them can fit in cache.
Is this an area where the best answer is "do what works now, and ask again when we get to Swift 5/6/etc"?
- Dave Sweeris
More information about the swift-users