我正在尝试通过使用Grand Central Dispatch的dispatch_apply方法来并行执行多个独立任务来加速我的iOS应用程序。 但是,这些任务共享一个只读资源(一个大的uint8_t数组),可以通过只读的非原子对象属性访问它。 由于它是只读资源,因此不需要同步访问。然而,共享的只读数组使执行速度极慢。它甚至比所有任务的串行执行慢。但是如果我为每个线程制作数组的本地副本,那么任务执行得非常快。
我不明白为什么我必须为每个线程创建一个副本,以便在只读资源的情况下从GCD中受益。是否有任何自动内部同步会导致执行时间变慢,因为GCD不知道它是一个只读资源?是否有可能在不为每个线程创建资源的本地副本的情况下防止减速?
非常感谢您提前!
答案 0 :(得分:2)
您可能会看到处理器之间的缓存行争用。您没有显示您使用dispatch_apply
的确切程度,但您可能会尝试实施dispatch_apply
手册页中所述的跨步策略。消除任何缓存行争用的关键是确保调度工作线程不会尝试访问占用相同缓存行的共享阵列的元素。
如果数组是动态分配的,它将从适当对齐的地址开始,因此您只需选择一个高速缓存行大小的倍数的步幅宽度。您可以放心地假设处理器的缓存行大小是64字节的一小部分,因此跨度宽度为128,256,512或1024是合理的。