- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个长时间运行(5-10 小时)的 Mac 应用程序,它处理 5000 个项目。每个项目都通过执行大量转换(使用 Saxon)、运行一堆脚本(使用 Python 和 Racket)、收集数据并将其序列化为一组 XML 文件、一个 SQLite 数据库和一个 CoreData 数据库来处理。每个项目都完全独立于其他所有项目。
总而言之,它做的很多,需要很长时间,而且似乎是高度可并行化的。
加载所有需要处理的项目后,应用程序使用 GCD 并行处理工作,使用 dispatch_apply
:
dispatch_apply(numberOfItems, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(size_t i) {
@autoreleasepool {
...
}
});
我在具有 12 个内核(24 个虚拟内核)的 Mac Pro 上运行该应用程序。所以我希望始终处理 24 个项目。但是,我通过日志记录发现正在处理的项目数量在 8 到 24 之间变化。这实际上是在增加运行时间(假设它可以一次处理 24 个项目)。 p>
一方面,也许 GCD 真的非常聪明,它已经给了我最大的吞吐量。但我担心的是,由于大部分工作都发生在该应用生成的脚本中,GCD 可能是根据不完整的信息进行推理,并没有做出最佳决策。
有什么提高性能的想法吗?正确后,第一个需要的属性是缩短该应用程序运行所需的时间。我不关心功耗、占用 Mac Pro 或其他任何东西。
更新:事实上,这在 docs 中看起来令人担忧:“并发队列在任何给定时刻执行的实际任务数是可变的,并且会随着应用程序中条件的变化而动态变化。许多因素会影响并发队列执行的任务数,包括可用内核数,< strong>其他进程正在完成的工作量,以及其他串行调度队列中任务的数量和优先级。” (强调)看起来让其他进程工作会对应用程序中的调度产生不利影响。
能够只说“同时运行这些 block ,每个内核一个,不要尝试做任何更聪明的事情”会很好。
最佳答案
如果您下定决心,可以使用 NSThread API 显式生成 24 个线程,并让每个线程从同步的工作项队列中拉取。我敢打赌性能会明显变差。
当提交给它的工作项从不阻塞时,GCD 的工作效率最高。也就是说,您所描述的工作负载相当复杂,并且充满了线程阻塞的机会。对于初学者来说,您正在生成一堆其他进程。就在这里,这意味着您已经依赖操作系统在您的主任务和这些从属任务之间分配时间/资源。除了设置每个子进程的操作系统优先级之外,操作系统调度程序无法知道哪些进程比其他进程更重要,默认情况下,您的子进程将与其父进程具有相同的优先级。也就是说,听起来您通过调整流程优先级没有任何好处。我假设您正在阻塞等待从任务完成的主任务线程。这实际上是停放该线程——它不能做任何有用的工作。但正如我所说,我认为调整从属任务的操作系统优先级不会有太多好处,因为这听起来确实像是一个 I/O 绑定(bind)工作流...
您继续描述三个 I/O 密集型操作(“将其序列化为一组 XML 文件、一个 SQLite 数据库和一个 CoreData 数据库。”)所以现在所有这些不同的线程和进程都在争夺什么大概是一个共享的大容量存储设备。 (即,除非您要写入 24 个不同的数据库,在 24 个独立的硬盘驱动器上,每个内核一个,否则您的过程最终将在磁盘访问时被序列化。)即使您有 24 个不同的硬盘驱动器,写入一个硬盘驱动器(甚至是 SSD)相对较慢。对于几乎任何阻塞的磁盘写入,您的线程将从它们正在运行的 CPU 中取出(以便另一个正在等待的线程可以运行)。
如果你想最大化你从 GCD 中获得的性能,你可能想要重写你在 C/C++/Objective-C 中的子任务中所做的所有事情,将它们引入进程中,然后使用 dispatch_io
原语进行所有相关的 I/O。对于您不控制低级读写的 API,您需要仔细管理和调整您的工作负载,以针对您拥有的硬件对其进行优化。例如,如果你有一堆东西要写入一个单一的、共享的 SQLite 数据库,那么让多个线程同时尝试写入该数据库是没有意义的。你最好让一个线程(或串行 GCD 队列)写入 SQLite 并在预处理完成后向其提交任务。
我可以在这里继续讲很长一段时间,但归根结底,这里的工作流程很复杂,看似受 I/O 限制。在最高级别,CPU 利用率或“正在运行的线程数”将成为此类任务的性能特别差的衡量标准。通过使用子进程(即脚本),您将大量控制权交给了操作系统,它实际上对您的工作负载一无所知,因此除了使用其通用调度程序分配资源外什么也做不了。 GCD 不透明的线程池管理实际上是您最不关心的问题。
在实际层面上,如果您想加快速度,请购买多个更快(即 SSD)的硬盘驱动器,然后重新设计您的任务/工作流程以单独和并行地使用它们。我怀疑这会为您带来最大的 yield (对于 time == money == hardware
的一些等价关系。)
关于objective-c - 如何加快 Mac 应用程序处理 5000 个独立任务的速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18245478/
我在想出一个算法时遇到了麻烦... 我有一系列 GPS 数据,以 1 秒为间隔记录时间、速度、距离。假设距离是米,速度是米/秒。可能有超过 2 小时的数据,或 7200 个点。这里的“时间”字段主要是
使用java排序器,即: Collections.sort(myArrayList, new Comparator() { @Override public int c
有什么区别吗 SELECT * FROM my_table 和 SELECT my_column_id FROM my_table 地点: my_table 有百万行 网站上有大量并发用户进行sql查
有2个样本。 在第一个示例中,使用 orderby 可以更快地获得结果。 (根据 phpmyadmin 速度报告) 在另一个例子中,我没有使用 order by,它给出的结果较慢。 (根据 phpmy
我注意到,如果我将训练数据加载到内存中并将其作为 numpy 数组提供到图中,与使用相同大小的 shuffle 批次相比,速度会有很大差异,我的数据有大约 1000 个实例。 使用内存 1000 次迭
我在 python 中使用破折号。我正在绘制记录到 SQLite 数据库中的实时数据,目前,我正在绘制单个值与时间线图。我计划再添加 20 个图表,但目前,随着时间的增加, plotly 变慢,我认为
我试图调用 hasNext Velocity 模板中的方法,以便根据 foreach 循环中的位置影响行为 - 仅 hasNext没有按照文档工作。 这是 Velocity 用户指南的片段,关于 ha
在我正在制作的游戏中,我有两个点,pt1 和 pt2,我想计算出它们之间的角度。我已经在较早的计算中计算出距离。显而易见的方法是对垂直距离上的水平距离进行反正切 (tan(theta) = opp/a
我经常遇到字符串值不存在和/或为空的情况。这是测试这种情况的最佳方法吗? #if( $incentive.disclaimer && $!incentive.disclaimer != '' )
我想将一个模板nested包含在其他模板cont1,cont2和cont3中。 并且嵌套模板应仅对cont1隐藏一个特定控件。 在包含在cont1中之前,我想为一些标志变量$hideMyControl
是否可以更改从“Windows Azure Media Encoder”输出的音频的播放速度? 我正在使用配置为“WMA High Quality Audio”的“Windows Azure Medi
我使用速度将String(template)与字段合并 hi there I'am ${name}, And I'am ${age} old. velocity将字段${name}和${age}与一种
我使用的是 LockedBitmap 类,它简化了 C# 中位图数据的处理。目前它正在将数据复制到本地 byte[] 数组中,然后通过其类方法访问该数组以获取/设置像素颜色值。 这比直接通过指针访问锁
我尝试在 VM_global_library.vm 文件中添加一堆 #set($x=abc) 语句,但这些变量在我的 VM 模板中不可用。 我想为图像的基本路径等设置一个全局变量。这可能吗? 最佳答案
我的项目结构: -src --main ---java ----makers -----SomeClass ---resources ----htmlPattern.vm 如何告诉 SomeClass
我正在尝试从 Velocity 中的字符串中删除不需要的字符(换行符可以,但不能像 EM 和 CAN ASCII 控制字符那样)。 #set($cleanScreen = $cleanScreen.r
我想在日.月.年之间的点处分割日期。例如:2015 年 1 月 14 日至 {14, 01, 2015}这是我使用的代码:dates3.get(0) 包含我从页面的文本字段获取的字符串“14.01.2
之后,从 1.5 升级到速度引擎 1.7 出现了 1.5 没有的问题。为了解释这个问题,我必须展示一个代码片段: #foreach($someVariable in $someCollection)
我想知道从表中选择所有字段是否更快: SELECT * 或只选择您真正需要的: SELECT field1, field2, field3, field4, field5... 假设表有大约 10 个
我正在尝试模仿照片应用程序的行为,在该应用程序中,用户用手指平移照片并且照片具有一定的速度。由于我不会深入的原因,我不能将 UIScrollView 与它的缩放 UIImageView 一起使用,而是
我是一名优秀的程序员,十分优秀!