On Oct 6, 2017, at 11:12 PM, Slava Pestov <spes...@apple.com> wrote:
>> On Oct 6, 2017, at 11:06 PM, Chris Lattner via swift-dev 
>> <swift-dev@swift.org> wrote:
>> This question is somewhere between swift-dev and swift-users, not sure where 
>> best to post this.  
>> 
>> I’m working on a project that wants to get very low-abstraction penalty 
>> array operations, particularly with varargs.
> 
> It’s awesome to hear you’re still using Swift ;-)

Indeed, it is nice to get to use it as well as hack on it, instead of largely 
just hacking on it :-).  OTOH, this makes me as impatient as everyone else to 
get conditional conformances, recursive conformances, varargs splat, and so 
many other things. :) :)

>> Is there a better way to achieve this, and if not, is there any planned work 
>> (perhaps aligned with the ABI stability efforts) to improve vararg array 
>> performance to be able to avoid heap abstractions?  Any individual call to a 
>> vararg array is a known length, so it is a perfect candidate for a stack 
>> allocation.
> 
> In fact I filed an internal radar about this a while ago, but the discussion 
> didn’t go anywhere because we had bigger fish to fry.

I think I confused things in my email.  The long term points that you mention 
are important (and I’ll comment on them below), but independently of the 
representation of varargs, there is a generally useful optimization that this 
code should be able to benefit from: when converting a statically knowable 
fixed sized array to an UnsafeBufferPointer (or UnsafePointer) for a call, we 
can get rid of the heap traffic in the client.  This is generally useful e.g. 
when calling into random C APIs.

I’m curious to know if anyone has thought about that or plans to work on it, 
because it would help for a lot of kinds of code, and is related to the 
existing “outlining” optimization. Coming back to varargs though:

> I think the main difficulty is that we would need some kind of 
> “copy-on-escape” sequence type. Iterating over the vararg inside the callee 
> should be efficient, but if I then take the value and store it somewhere 
> else, it would need to copy the buffer from the stack to the heap.
> Also there were source stability implications because people assume the 
> vararg argument inside the function body is literally a Swift.Array.
> Perhaps the work being done on ownership can help here though. In the 
> ownership manifesto, John describes a ‘shared’ attribute on function 
> parameters. 


Right.  If we ignore source compatibility for the moment, it seems clear that 
the best callee side representation for varargs is a borrowing array slice 
(like llvm::ArrayRef or UnsafeBufferPointer).  This provides the essential 
abstraction needed by varargs without forcing an onerous representation on the 
caller, and without implying any reference counting operations.  This would 
allow passing an Array, an ArraySlice, a StaticArray, or anything else with 
contiguous elements.

> What if I declare my vararg as shared:
> 
> func takesArgs(_ xs: shared Int…)

This seems like a great way to address the source compatibility issue: a normal 
varargs argument could be passed as an Array<T> for compatibility with existing 
source, and a “borrowed Int…” could be passed more efficiently, allowing folks 
to opt into that.

> This means the caller is passing along a borrowed value, not the value 
> itself. With today’s vararg implementation this would just pass the 
> Array<Int> at +0, but perhaps this can be the extension point where we 
> introduce the stack-allocated varargs that you propose, and say that a 
> ‘shared’ vararg argument actually has a more efficient representation. This 
> allows it to be introduced additively without breaking ABI or source 
> compatibility.
> 
> What do you think?

This would be totally awesome.  How much do you think that people depend on 
varargs being an escapable array inside the body of functions?  It would be 
much cleaner to just make them nonescaping slices all the time.

-Chris

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to