27

正如标题所示,NSOperationQueue 的 maxConcurrentOperationCount 的默认值是多少?

它是否设置为值 1?

4

3 回答 3

33

文档中,

使用 setMaxConcurrentOperationCount: 方法在接收器上显式设置的最大并发操作数。如果没有显式设置值,则此方法默认返回 NSOperationQueueDefaultMaxConcurrentOperationCount

所以它是NSOperationQueueDefaultMaxConcurrentOperationCount。如果设置了此项,它将根据可用处理器的数量和其他相关因素选择适当的值。

这是它的定义方式

enum {
  NSOperationQueueDefaultMaxConcurrentOperationCount = -1
};

NSOperationQueueDefaultMaxConcurrentOperationCount:默认的最大操作数由 NSOperationQueue 对象根据当前系统条件动态确定。

于 2013-02-21T06:23:31.067 回答
3

在我的一个应用程序中,我一次添加了大约 35kNSOperation个实例NSOperationQueue。如果我设置maxConcurrentOperationCount为 64,与默认值相比,我获得了大约 20 倍的性能。CPU 负载从 ~120% 上升到 400%,这似乎表明默认值太高以至于 CPU 主要忙于处理操作队列开销。

结论:如果你有很多短暂的生命NSOperation,那么玩maxConcurrentOperationCount.

于 2019-10-07T23:45:01.407 回答
1

maxConcurrentOperationCountofNSOperationQueue在 iPhone 平台上只能设置为 1 到 6。

maxConcurrentOperationCount设置为NSOperationQueue默认值不是一个好主意。因为这意味着无限数量的队列。

什么时候应该将maxConcurrentOperationCountofNSOperationQueue 设置为 1 到 6 ?

当可以同时调用多个任务时,maxConcurrentOperationCountofNSOperationQueue应该设置为6。例如,可以同时下载多个图像。

为什么是 6 而不是 10 或 100?

在名为 的框架SDWebImage中,我们可以看到源代码如下:

- (instancetype)init {
   self = [super init];
   if (self) {
       _maxConcurrentDownloads = 6;
       _downloadTimeout = 15.0;
       _executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
       _acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)];
   }
   return self;
}

此代码表示默认值为 6。 SDWebImage 参考 SDWebImageDownloaderConfig 类参考

的含义 maxConcurrentDownloadsmaxConcurrentOperationCountApple-Docs-NSOperationQueue-maxConcurrentOperationCount)相同

为什么是 6 而不是 10 或 100?

SDWebImage 说它的编码器是通过实验:

参考:为什么 SDWebImageDownloader maxConcurrentOperationCount = 6?#1961

忽略实验, 从 iPhone 到 iPhone 13/13 Pro/13 Pro Max,iOS 平台上处理器核心的最大数量是 6 个,所以应该设置为 1 到 6 maxConcurrentOperationCountNSOperationQueue

苹果手机 首次发布 系统开启 处理器核心数
苹果手机 2007年 S (三星 S5L8900) 1个核心
iPhone 3G 2008年 S (三星 S5L8900) 1个核心
iPhone 3GS 2009 S(三星S5PC100 1个核心
iPhone 4 2010 A4 1个核心
iPhone 4S 2011 A5 2个核心
iphone 5 2012 A6 2个核心
iPhone 5S 2013 A7 2核
iPhone 6/6 加 2014 A8 2个核心
iPhone 6s/6s plus/SE 2015 A9 2个核心
iPhone 7/加 2016 年 A9 4核(使用2核)
iPhone 8/加/X 2017 A11 6 个核心 = 2 个高功率 Monsoon 核心 + 4 个低功率 Mistral 核心
iPhone XS/XS MAX/XR 2018 A12 6 个核心 = 2 个高功率 Vortex 核心 + 4 个低功率 Tempest 核心
iPhone 11 /11 Pro/11 Pro Max 2019 A13 6 个核心 = 2 个性能 + 4 个效率核心
iPhone 12 /12 Pro/12 Pro Max 2020 A14 6 个核心 = 2 个性能 + 4 个效率核心
iPhone 13 /13 Pro/13 Pro Max 2021 A15 6 个核心 = 2 个性能 + 4 个效率核心

我们可以使用如下代码打印处理器内核的数量:

   NSUInteger cpuCoresCount = [[NSProcessInfo processInfo] processorCount];

我们可以使用如下代码打印活动处理器内核的数量:

   NSUInteger activeCPUCoresCount = [[NSProcessInfo processInfo] activeProcessorCount];

参考文档:Apple-Docs-NSProcessInfo-processorCount

_maxConcurrentDownloads在 iPhone 平台上设置为 CPU 核心数是合理 的。至于进一步的评论,activeProcessorCount可能会更好。

在名为 的框架中YYKitqueueCount设置为activeProcessorCount.

#define MAX_QUEUE_COUNT 16
   static int queueCount;
   static dispatch_queue_t queues[MAX_QUEUE_COUNT];
   static dispatch_once_t onceToken;
   static int32_t counter = 0;
   dispatch_once(&onceToken, ^{
       queueCount = (int)[NSProcessInfo processInfo].activeProcessorCount;
       queueCount = queueCount < 1 ? 1 : queueCount > MAX_QUEUE_COUNT ? MAX_QUEUE_COUNT : queueCount;
       if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
           for (NSUInteger i = 0; i < queueCount; i++) {
               dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0);
               queues[i] = dispatch_queue_create("com.ibireme.yykit.render", attr);
           }
       } else {
           for (NSUInteger i = 0; i < queueCount; i++) {
               queues[i] = dispatch_queue_create("com.ibireme.yykit.render", DISPATCH_QUEUE_SERIAL);
               dispatch_set_target_queue(queues[i], dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
           }
       }
   });
   int32_t cur = OSAtomicIncrement32(&counter);
   if (cur < 0) cur = -cur;
   return queues[(cur) % queueCount];
#undef MAX_QUEUE_COUNT

什么时候应该设置maxConcurrentOperationCountNSOperationQueue 1 ?

它们设置maxConcurrentOperationCount为一个意味着只能同时调用一个任务。

当只能同时调用一个任务时, maxConcurrentOperationCount应设置为1。例如,只能同时动画一张GIF图像;只能同时播放一个视频。此外,只能同时解码一个视频/图像。

参考:Apple-Docs-NSOperationQueue-maxConcurrentOperationCount

于 2021-11-17T12:37:38.710 回答