https://twitter.com/steipete/status/676851647042203648
我将不发表任何评论(我只是说...如果在iOS上是非法的,为什么它是公共API?)
显然pthread
互斥体现在更快了。 我们应该创建一个基准进行比较,然后尝试将Atomic
转换为此(以及RACCompoundDisposable
和RACSerialDisposable
吗?)
我什至不知道“非法”是什么意思。
我只是很好奇,因为我从一开始就不在身边,但是为什么Atomic
类型首先使用OSSpinLock
Atomic
类型呢?
是否使用了NSLock
,然后显示它太慢,然后对pthread_mutex_t
进行了测试,发现它也太慢了? 不幸的是,git在“移动源……”之前没有历史记录
我不希望在非内核,非设备驱动程序的上下文中使用自旋锁,这就是我问的原因。 如果有的话,我会说这里的错误是根本使用了OSSpinLock
。 :stuck_out_tongue:
为了在我上面的评论中添加一个对策,这并没有标题那么大的麻烦: https :
即使在CPU不足的情况下,关键部分也是如此之小,在实际情况下可能还可以。
— @Twitter上的
至于@kastiglione的上述评论:
我什至不知道“非法”是什么意思。
我没有答案,但是我猜想ARM CPU中的某些东西不允许自旋锁原语享受与Intel CPU一样的许多好处/保证/假设。 (但根据https://twitter.com/Catfish_Man/status/676851988596809728可能不是全部)
无论如何,在实践中可能“什么也看不到”,而是应该进行一些研究以替换为更安全的原语,并测量任何性能下降,如
我确实认为我们应该替换对OSSpinLock
,但是鉴于给我们提供的文档,我认为使用它们的理由是有效的。
是的,并且感谢您提供的相关历史记录。 不知道为什么当请求给定文件的历史记录时GitHub不执行git log --follow
。
无论如何,我将重申“可能很好”。 使用“现在更快”的互斥锁可能是一项简单的任务,但是在不知道如何配置/测试它们的情况下却并非如此。 那里有任何建议/指针吗?
至于如果/当性能成为问题时的前进之路,无锁队列值得研究。 (对于不熟悉该概念的读者,这是一篇不错的文章:http://www.linuxjournal.com/content/lock-free-multi-producer-multi-consumer-queue-ring-buffer?page = 0,0)。 不久前,我为内部音频库构建了类似的东西,也许我可以像这样将其改编为一般用途。
使用“现在更快”的互斥锁可能是一项简单的任务,但是在不知道如何配置/测试它们的情况下却并非如此。 那里有任何建议/指针吗?
我在Instruments的Time Profiler和Allocations中运行GitHub Desktop,并专注于RAC繁重的堆栈。 您现在必须与@joshaber或@mdiep交谈。 :眨眼:
好的,很高兴知道。 我想象Swift端的东西将需要类似的大/深代码库来进行测试。 我已经长大了一些我自己在过去的几个月中1,但我不知道我是否推RAC“够硬”,以获得足够的样品出来。 诸如我的应用程序会在其他工具图表中冒出很多其他东西。 :微笑:
1个插头! http://capoapp.com ,其中http://capoapp.com/neptune是最新的,完全设计的using-RAC4组件。
我今天写了一篇博客文章,详细介绍了为什么自旋锁在iOS上“非法”: http :
我不久前中断了Atomic,并将其迁移到pthread_mutex_lock。 众所周知,这是最好的锁–没有像NSLock这样的动态调度,没有像spinlock这样的即时锁,不会像spin lock那样浪费能量。
随意从我的仓库中复制粘贴源代码,或使用它做任何你想做的事情。
https://github.com/Adlai-Holler/Atomic
https://github.com/Adlai-Holler/Atomic/blob/master/Atomic/Atomic.swift
@kballard ,这是一个很好的解释,谢谢!
我对此不是很坚决,因为我不是这方面的专家。 尽管我很乐意自己进行更改,但我会决定更改(或不更改)我们使用哪种类型的锁,因此请他人参考!
没有源代码,这样的基准完全没有用。 而且,您只为每个结构显示一个时间,而没有记录该时间实际代表的时间。 各种构造的行为会有所不同,具体取决于它们是否处于争用状态,争用锁的线程的优先级等。 @synchronized
也是一个奇怪的野兽,其性能将在很大程度上取决于访问模式,例如,同时要输入/退出多少个@synchronized
块,是重复锁定同一对象还是锁定新对象,等等。
注意: dispatch_semaphore
不捐赠优先级,这是另一个潜在的陷阱。
@jspahrsummers @kballard我有一个使用原子CAS的实现。 如果有任何兴趣,我很乐意提交PR。
编辑:查看Atomic
的使用,我认为我的实现不会有用。 如果您可以进行幂等更新,则CAS可以使您在内存中进行某种乐观的事务,这可能很棒,但是需要进行大量重构(尽管如果所有内容都是CoW不可变的,那么它确实工作得很好,那么您确实可以将突变视为内存中的交易)。
我今天发现了这个线程,并对不同类型的同步进行了调查,并在iOS模拟器和真实设备上执行了基准测试。
结果对我来说非常有趣。 在iOS 10中,dispatch_semaphore的性能明显下降,这可能是出于线程优先级方面的改变。
这是iOS中可用的基本同步机制的摘要图。 所有测试均使用发布配置运行(快速优化-O)
您的电话号码对我来说似乎很可疑。 您运行了多少次测试?
为了进行比较,我在OS X 10.11.5上运行了自己的基准测试(源代码),使用了我不久前写的hacky基准测试工具。 我运行了整个基准测试10次,从每个测试中删除了底部和顶部2个数字(以消除异常值),其余数字产生了以下范围:
无同步:22-41ns
自旋锁:24ns
信号量:29ns
NSLock:45-71ns
互斥体:40-64ns
同步:75-122ns
队列:505-554ns
从中可以看出,自旋锁是最便宜的,其次是信号量,然后是互斥锁,然后是NSLock,紧随互斥锁之后(因为它基本上是互斥锁+ objc_msgSend),然后同步的开销几乎是后者的两倍,最后队列最终变得极其昂贵昂贵,比我预期的要贵得多。
如您所见, @ kballard ,我的基准测试非常简单,但是它使用默认的xctest机制来衡量执行时间。 数字是每个测试的平均运行时间,而不是每个同步的平均运行时间。 通常,您和我的结果是相关的,除了队列,我们以前认为还不错
原因
最有用的评论
我今天发现了这个线程,并对不同类型的同步进行了调查,并在iOS模拟器和真实设备上执行了基准测试。
结果对我来说非常有趣。 在iOS 10中,dispatch_semaphore的性能明显下降,这可能是出于线程优先级方面的改变。
这是iOS中可用的基本同步机制的摘要图。 所有测试均使用发布配置运行(快速优化-O)
SDK9的基准代码
SDK10的基准代码