[swift-users] Are structs really always pessimistically copied when calling funcs?

Karl Pickett karl.pickett at gmail.com
Sun Dec 6 19:16:38 CST 2015


I have a struct and this code:

func test() {
    precondition(sizeof(Foo) == 128)

    let s = Foo()
    for _ in 0..<100_000_000 {
        doSomething(s)
    }
}

The asm (on LInux, with -O) is showing me that s is being re-initialized on
every iteration of the loop.  I was hoping that thanks to swift's strict
constness rules on structs, it wouldn't have to do this - and just pass the
same pointer to doSomething() each time.

When I use an inout param, that is 2x as fast and doesn't re-initialize
each time.  However I don't see why passing something immutably wouldn't be
as fast.

- Karl

asm from perf:

  2.71 │50:┌─→xorps  %xmm0,%xmm0
                                               ▒
  8.06 │   │  movaps %xmm0,-0x20(%rbp)
                                               ▒
  2.71 │   │  movaps %xmm0,-0x30(%rbp)
                                               ▒
  7.41 │   │  movaps %xmm0,-0x40(%rbp)
                                               ▒
 10.59 │   │  movaps %xmm0,-0x50(%rbp)
                                               ▒
 10.00 │   │  movaps %xmm0,-0x60(%rbp)
                                               ▒
  9.53 │   │  movaps %xmm0,-0x70(%rbp)
                                               ▒
 10.65 │   │  movaps %xmm0,-0x80(%rbp)
                                               ▒
 11.24 │   │  movaps %xmm0,-0x90(%rbp)
                                               ▒
 12.06 │   │  mov    %r14,%rdi
                                               ▒
  3.41 │   │→ callq  _TF4main11doSomethingFVS_3FooT_
                                               ▒
  2.82 │   │  dec    %rbx
                                              ▒
  8.82 │   └──jne    50

main.swift:

struct Vec4 {
    var a: Int64 = 0
    var b: Int64 = 0
    var c: Int64 = 0
    var d: Int64 = 0
}

struct Foo {
    var x: Vec4 = Vec4()
    var y: Vec4 = Vec4()
    var z: Vec4 = Vec4()
    var u: Vec4 = Vec4()
}

func test() {
    precondition(sizeof(Foo) == 128)

    let s = Foo()
    for _ in 0..<100_000_000 {
        doSomething(s)
    }
}

test()


lib.swift:

func doSomething(s: Foo) {
    precondition(s.x.a != 1)
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20151206/23c5c3ec/attachment.html>


More information about the swift-users mailing list