目标c – GCD表现不佳

前端之家收集整理的这篇文章主要介绍了目标c – GCD表现不佳前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
你可能记得,我试图使用GCD来加快我的一些代码,即碰撞检测和解析引擎.但是,我显然做错了,因为我的所有GCD代码都比我的序列号慢得多(1.4x和10x之间).请允许我举个例子:我以气泡排序的方式迭代数组,以确定该数组中对象之间的所有可能的冲突:
  1. - (double) detectCollisionsInArray:(NSArray*)objects
  2. {
  3. int count = [objects count];
  4. if (count > 0)
  5. {
  6. double time = CFAbsoluteTimeGetCurrent();
  7. for (int i = 0; i < count; i++)
  8. {
  9. for (int j = i + 1; j < count; j++)
  10. {
  11. /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
  12. }
  13. }
  14.  
  15. return CFAbsoluteTimeGetCurrent() - time;
  16. }
  17.  
  18. return 0;
  19. }

相当直截了当,考虑到问题的限制,它似乎表现良好.但是,我想利用每个对象的状态在代码段中不被修改,并使用GCD来并行化这个工作.为此,我正在尝试这样的事情:

  1. - (double) detectCollisionsInArray:(NSArray*)objects
  2. {
  3. int count = [objects count];
  4. if (count > 0)
  5. {
  6. NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
  7. NSBlockOperation* blockOperation = nil;
  8.  
  9. double time = CFAbsoluteTimeGetCurrent();
  10. for (int i = 0; i < count; i++)
  11. {
  12. for (int j = i + 1; j < count; j++)
  13. {
  14. void (^workBlock) (void) = ^()
  15. {
  16. /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
  17. };
  18.  
  19. if (!blockOperation)
  20. {
  21. blockOperation = [NSBlockOperation blockOperationWithBlock:b];
  22. }
  23. else
  24. {
  25. [blockOperation addExecutionBlock:workBlock];
  26. }
  27. }
  28. }
  29.  
  30. [opQueue addOperation:blockOperation];
  31. [opQueue autorelease];
  32.  
  33. return CFAbsoluteTimeGetCurrent() - time;
  34. }
  35.  
  36. return 0;
  37. }

任何人都可以帮助我走上正确的轨道,或者提供一个良好的GCD教程的链接?我已经浏览了几个GCD教程,并扫描了所有的文档,我仍然觉得我对这个问题的掌握至关重要.谢谢!

解决方法

有没有理由不使用GCD C API和dispatch_ *系列函数?您对NSOperationQueue的GCD方面没有太多的控制(比如要提交块的队列).另外,我不知道你是否使用iOS,但NSOperationQueue在iOS上并没有使用GCD.这可能是它产生了这么多线程的原因.无论哪种方式,如果直接使用GCD API,您的代码将会更简单和简单:
  1. - (double) detectCollisionsInArray:(NSArray*)objects
  2. {
  3. int count = [objects count];
  4. if (count > 0)
  5. {
  6. double time = CFAbsoluteTimeGetCurrent();
  7.  
  8. dispatch_group_t group = dispatch_group_create();
  9. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
  10. for (int i = 0; i < count; i++)
  11. {
  12. dispatch_group_async(group,queue,^{
  13. for (int j = i + 1; j < count; j++)
  14. {
  15. dispatch_group_async(group,^{
  16. /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
  17. });
  18. }
  19. });
  20. }
  21. dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
  22. dispatch_release(group);
  23. return CFAbsoluteTimeGetCurrent() - time;
  24. }
  25. return 0;
  26. }

您可以使用dispatch_group将所有执行组合在一起,并等待所有执行完成dispatch_group_wait.如果您不想知道块的完成情况,您可以忽略组件部分,只需使用dispatch_async. dispatch_get_global_queue函数将获得3个并发队列之一(低,默认或高优先级),以便将块提交到.你不必担心限制线程数或任何类似的事情. GCD调度程序应该为你做所有这些.只要确保提交到一个并发队列,它可以是3个全局队列之一,或者通过将DISPATCH_QUEUE_CONCURRENT传递给dispatch_queue_create创建的队列(这可以从OS X 10.7和iOS 5.0开始).

如果您在每个块中执行一些文件I / O或对某些其他资源征税,则可能需要在GCD中进行统计,并一次限制要提交到队列的块数.这将与限制NSOperationQueue中的并发操作计数具有相同的效果.您可以使用GCD信号量来做到这一点:

  1. - (double) detectCollisionsInArray:(NSArray*)objects
  2. {
  3. int count = [objects count];
  4. if (count > 0)
  5. {
  6. double time = CFAbsoluteTimeGetCurrent();
  7.  
  8. dispatch_group_t group = dispatch_group_create();
  9. dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
  10. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
  11. for (int i = 0; i < count; i++)
  12. {
  13. dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
  14. dispatch_group_async(group,^{
  15. for (int j = i + 1; j < count; j++)
  16. {
  17. dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
  18. dispatch_group_async(group,^{
  19. /** LOTS AND LOTS OF WORK FOR EACH OBJECT **/
  20. dispatch_semaphore_signal(semaphore);
  21. });
  22. }
  23. dispatch_semaphore_signal(semaphore);
  24. });
  25. }
  26. dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
  27. dispatch_release(group);
  28. dispatch_release(semaphore);
  29. return CFAbsoluteTimeGetCurrent() - time;
  30. }
  31. return 0;
  32. }

一旦你得到它的悬挂,GCD是非常简单的使用.我现在使用它在我的代码.

Can anyone help to put me on the right track and perhaps provide a link to a good GCD tutorial?

运行,不要走到Mike Ash’s blog.他的GCD系列是我看到的最清晰和最简洁的,只需要你大约30分钟来阅读整个事情.苹果的WWDC视频从2010年的GCD和块也不错.

猜你在找的C&C++相关文章