ios NSOperationQueue的maxConcurrentOperationCount的默认值

eblbsuwk  于 2023-07-01  发布在  iOS
关注(0)|答案(3)|浏览(109)

正如标题所示,NSOperationQueue的maxConcurrentOperationCount的默认值是多少?
是否设置为值1?

5t7ly7z5

5t7ly7z51#

从文件来看,
使用setMaxConcurrentOperationCount在接收方上显式设置的最大并发操作数:method.如果没有显式设置值,则此方法默认返回NSOperationQueueDefaultMaxConcurrentOperationCount
所以它是NSOperationQueueDefaultMaxConcurrentOperationCount。如果设置了此值,它将根据可用处理器的数量和其他相关因素选择适当的值。
下面是it is defined

enum {
  NSOperationQueueDefaultMaxConcurrentOperationCount = -1
};

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

wgxvkvu9

wgxvkvu92#

在我的一个应用程序中,我一次将大约35 k个NSOperation示例添加到NSOperationQueue中。如果我将maxConcurrentOperationCount设置为64,与默认值相比,我获得了大约20倍的性能。CPU负载从~120%上升到400%,这似乎表明默认值太高,以至于CPU主要忙碌处理操作队列开销。
结论:如果你有很多短暂的NSOperation,那么使用maxConcurrentOperationCount可能是值得的。

yzuktlbb

yzuktlbb3#

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

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

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

当可以同时调用多个任务时,NSOperationQueuemaxConcurrentOperationCount应设置为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类参考
maxConcurrentDownloads的含义与maxConcurrentOperationCountApple-Docs-NSOperationQueue-maxConcurrentOperationCount)相同
为什么是6个而不是10个或100个?
SDWebImage的编码器说,这是通过实验:
参考:Why SDWebImageDownloader maxConcurrentOperationCount = 6? #1961
忽略实验,NSOperationQueuemaxConcurrentOperationCount应该设置为1到6,因为从iPhone到iPhone 14 /14 Pro/14 Pro Max,iOS平台上的最大处理器核心数为6。
| 首次发布|系统开启|处理器核心数| number of processor cores |
| --|--|--| ------------ |
| 二零零七年|S(Samsung S5L8900)|1芯| 1 core |
| 二零零八年|S(Samsung S5L8900)|1芯| 1 core |
| 2009年|S(三星S5 PC 100| 1芯| 1 core |
| 2010年|A4| 1芯| 1 core |
| 2011年|A5| 2芯| 2 cores |
| 二〇一二年|A6| 2芯| 2 cores |
| 2013年|A7| 2芯| 2cores |
| 二○一四年|A8| 2芯| 2 cores |
| 2015年|A9| 2芯| 2 cores |
| 2016年|A9| 4芯(使用2芯)| 4 cores (2 cores used) |
| 2017年|A11| 6个核心= 2个高功率季风核心+4个低功率西北风核心| 6 cores = 2 high power Monsoon cores + 4 low power Mistral cores |
| 2018年|A12| 6个内核= 2个高功率Vortex内核+4个低功率Tempest内核| 6 cores = 2 high power Vortex cores + 4 low power Tempest cores |
| 2019年|A13| 6个内核= 2个高性能内核+ 4个高效率内核| 6 cores = 2 performance + 4 efficiency cores |
| 二〇二〇年|A14| 6个内核= 2个高性能内核+ 4个高效率内核| 6 cores = 2 performance + 4 efficiency cores |
| 二〇二一|A15| 6个内核= 2个高性能内核+ 4个高效率内核| 6 cores = 2 performance + 4 efficiency cores |
| 2022| A15| 6个内核= 2个高性能内核+ 4个高效率内核| 6 cores = 2 performance + 4 efficiency cores |
我们可以用下面的代码打印处理器内核的数量:

NSUInteger cpuCoresCount = [[NSProcessInfo processInfo] processorCount];

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

NSUInteger activeCPUCoresCount = [[NSProcessInfo processInfo] activeProcessorCount];

参考文件:Apple-Docs-NSProcessInfo-processorCount
在iPhone平台上设置_maxConcurrentDownloads作为CPU核心数是合理的。至于进一步的评论,activeProcessorCount可能更好。
在名为YYKit的框架中,queueCount被设置为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

NSOperationQueuemaxConcurrentOperationCount什么时候应该设置为1?

他们将maxConcurrentOperationCount设置为一个意味着只能同时调用一个任务。
当只能同时调用一个任务时,maxConcurrentOperationCount应设置为1。例如,只能同时动画一个GIF图像;只能同时播放一个视频。此外,仅一个视频/图像可以被同时解码。
参考:Apple-Docs-NSOperationQueue-maxConcurrentOperationCount

相关问题