简体   繁体   English

GCD串行队列是否使用所有CPU内核?

[英]Does a GCD serial queue use all CPU cores?

i want to render 30 different images. 我想渲染30个不同的图像。 Each task has to merge different image layers to just one final image- 30 final images. 每个任务必须将不同的图像层合并为一个最终图像-30个最终图像。

Currently i use a GCD serial queue. 目前,我使用GCD串行队列。 Now i want to know if this approach uses the CPU power of all available cores automatically? 现在我想知道这种方法是否自动使用所有可用内核的CPU功能?

Or can i improve the rendertime for all these tasks when using a GCD concurrent queue instead? 还是使用GCD并发队列代替所有这些任务的渲染时间? Thanks for clarification.. 感谢您的澄清。

Serial queue = 1 task = 1 core. 串行队列= 1个任务= 1个核心。 But the real problem in your use case is I/O contention. 但是用例中的真正问题是I / O争用。 What happens if you spawn a concurrent queue to read from one resource? 如果产生并发队列以从一种资源读取会发生什么情况? you end up with the CPU(s) sitting idle on each block while they take turns reading the disk. 最终,当CPU轮流读取磁盘时,它们在每个块上都处于空闲状态。 GCD reacts to idle CPU increasing the thread pool. GCD对空闲CPU作出反应,增加了线程池。 In this case that results in too many threads and even more contention. 在这种情况下,这会导致线程过多,甚至导致更多争用。

The solution is to use dispatch_io functions for the reading, and do the image processing on a different concurrent queue, which will be free to grow as needed. 解决方案是使用dispatch_io函数进行读取,并在不同的并发队列上进行图像处理,该队列可以根据需要自由增长。

dispatch_queue_t imageProcessing = dispatch_queue_create("com.yourReverseDomainHere", DISPATCH_QUEUE_CONCURRENT);

for (NSURL *url in ...){
    dispatch_io_t io = dispatch_io_create_with_path(DISPATCH_IO_RANDOM,[[url path] fileSystemRepresentation], O_RDONLY, 0, NULL, NULL);
    dispatch_io_set_low_water(io, SIZE_MAX);
    dispatch_io_read(io, 0, SIZE_MAX, dispatch_get_main_queue(),^(bool done, dispatch_data_t data, int error){

        // convert the file from dispatch_data_t to NSData
        const void *buffer = NULL;
        size_t size = 0;
        dispatch_data_t tmpData = dispatch_data_create_map(data, &buffer, &size);
        NSData *nsdata = [[NSData alloc] initWithBytes:buffer length:size];
        dispatch_release(tmpData);
        free(buffer);

        // send this nsdata elsewhere for processing
        dispatch_async(imageProcessing, ^{
            // ...image processing code...
        });

    });
}

串行队列一次运行一个任务,因此每个串行队列一次仅使用一个内核(尽管在任何时候都不会使用哪个内核,并且可以更改)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM