gpt4 book ai didi

swift - 为什么单线程swift会出现内存冲突?

转载 作者:行者123 更新时间:2023-12-03 08:29:54 27 4
gpt4 key购买 nike

引用official tutorial ,然而,根据我的 JavaScript 知识,Swift 中存在内存冲突,不存在内存冲突,下面的代码永远是正确的。

func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}
var playerOneScore = 42
var playerTwoScore = 30
balance(&playerOneScore, &playerTwoScore) // OK
balance(&playerOneScore, &playerOneScore) // Error: conflicting accesses to playerOneScore

最佳答案

来自Memory Safety :

Specifically, a conflict occurs if you have two accesses that meet allof the following conditions:

  • At least one is a write access or a nonatomic access.
  • They access the same location in memory.
  • Their durations overlap.

之后:

A function has long-term write access to all of its in-out parameters.The write access for an in-out parameter starts after all of thenon-in-out parameters have been evaluated and lasts for the entireduration of that function call.

因此,将相同的变量作为输入输出参数传递给

func balance(_ x: inout Int, _ y: inout Int) 

算作对同一内存位置的重叠写访问,因此算作冲突。

有关基本原理和更多详细信息,请参阅 SE-0176 Enforce Exclusive Access to Memory ,已在 Swift 4 中实现。特别是,强制执行独占内存访问

  • 防止未定义的行为以及意外或令人困惑的结果。
  • 允许编译器对加载和存储做出乐观假设。

举个例子,如果将相同的变量作为 inout 参数传递,则以下两个看似等效的函数实际上并不等效,因此改变 x 会影响 y反之亦然:

func balance(_ x: inout Int, _ y: inout Int) {
let sum = x + y
x = sum / 2
y = sum - x
}

func balance(_ x: inout Int, _ y: inout Int) {
x = (x + y) / 2
y = (x + y) / 2 - x
}

另一个例子:

var global = 0
func foo(_ x: inout Int, _ y: inout Int) {
x += y
global = y
}

如果改变x可能会修改y,反之亦然,则编译器无法优化代码以首先将y的值加载到寄存器中,即执行相当于

func foo(_ x: inout Int, _ y: inout Int) {
let savedY = y
x += savedY
global = savedY
}

还讨论了(参见 Eliminating non-instantaneous accesses? )通过在函数调用期间制作临时副本来消除长期访问,这些临时副本在函数返回时分配回来,即执行类似的操作

func balance(_ x: inout Int, _ y: inout Int) {
var (localX, localY) = (x, y)
let sum = localX + localY
localX = sum / 2
localY = sum - localX
(x, y) = (localX, localY)
}

这个想法被放弃了,因为它对性能不利,即使对于“简单类型”来说也是如此,但对于像Array这样的“容器类型”来说更糟糕。

关于swift - 为什么单线程swift会出现内存冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65439530/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com