objective-c – 重用一个导致奇怪性能损失的CGContext

objective-c – 重用一个导致奇怪性能损失的CGContext,第1张

概述我的课堂是在屏幕外面渲染图像。我认为重复使用CGContext而不是一次又一次地为每个图像创建相同的上下文将是一件好事。我设置了一个成员变量_imageContext,所以我只需要创建一个新的上下文,如果_imageContext是这样的: if(!_imageContext) _imageContext = [self contextOfSize:imageSize]; 代替: CGCo 我的课堂是在屏幕外面渲染图像。我认为重复使用CGContext而不是一次又一次地为每个图像创建相同的上下文将是一件好事。我设置了一个成员变量_imageContext,所以我只需要创建一个新的上下文,如果_imageContext是这样的:

if(!_imageContext)    _imageContext = [self contextOfSize:imageSize];

代替:

CGContextRef imageContext = [self contextOfSize:imageSize];

当然,我不再发布CGContext了。

这些是我做出的唯一的改变,结果是重用上下文将渲染速度从10ms延迟到60ms。我错过了什么吗?在再次绘制之前,我必须清除上下文吗?还是重新创建每个图像的上下文的正确方法?

编辑

找到最奇怪的连接..

当我在搜索应用程序的内存在应用程序开始渲染图像时令人难以置信的原因,我发现问题是我将渲染的图像设置为NSImageVIEw。

imageVIEw.image = nil;imageVIEw.image = [[NSImage alloc] initWithCGImage:_imageRef size:size];

看起来ARC并没有释放以前的NSImage。第一种避免这种情况的方法是将新的形象画成旧的形象。

[imageVIEw.image lockFocus];[[[NSImage alloc] initWithCGImage:_imageRef size:size] drawInRect:NSMakeRect(0,size.wIDth,size.height) fromrect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];[imageVIEw.image unlockFocus];[imageVIEw setNeedsdisplay];

内存问题已经消失,CGContext重用问题发生了什么?
不重用上下文现在需要20ms而不是10ms – 当然,绘制图像比仅仅设置它更长。
重用上下文也需要20ms而不是60ms。但为什么?我看不到有任何连接,但是我可以通过设置NSImageVIEw的图像而不是绘制它来再现旧的状态,重复使用需要更多的时间。

解决方法 我调查了这一点,我观察到同样的放缓。查看仪器设置为采样内核调用以及用户调用显示了罪魁祸首。 @ RyanArtecona的评论是正确的。我在两个测试运行(一个重用上下文,另一个重新创建一个新的上下文)中,将最下面的用户名调用CGScolorMaskcopyARGB8888_sse集中在一起,然后将生成的调用树反转。在上下文不被重用的情况下,我看到最重的内核跟踪是:

Running Time    Self            Symbol name668.0ms   32.3% 668.0           __bzero668.0ms   32.3% 0.0              vm_fault668.0ms   32.3% 0.0               user_trap668.0ms   32.3% 0.0                CGScolorMaskcopyARGB8888_sse

这是通过CGScolorMaskcopyARGB8888_sse访问它们而导致内存归零的内存页面。这意味着CGContext将VM页面映射到位图上下文,但内核实际上并没有执行与该 *** 作相关联的工作,直到有人实际访问该内存。实际的映射/故障发生在第一次访问。

现在我们来看看最重的内核跟踪,当我们重用上下文时:

Running Time            Self            Symbol name1327.0ms   35.0%        1327.0          bcopy1327.0ms   35.0%        0.0              user_trap1327.0ms   35.0%        0.0               CGScolorMaskcopyARGB8888_sse

这是内核复制页面。我的钱将是这样的底层写作机制,提供@RyanArtecona在他的评论中所谈论的行为:

In the Apple docs for CGBitmapContextCreateImage,it says the actual
bit-copying operation doesn’t happen until more drawing is done on the
original context.

在设计的情况下,我曾经测试过,非重用案例执行了3392ms,重用案例花费了4693ms(明显慢)。考虑到每种情况下只有单一最重的踪迹,内核跟踪表明我们在第一次访问时花费668.0ms零填充新页面,在图像获取参考后,首次写入时写入写入页上的页面为1327.0ms到那些页面。这是659ms的差异。两者之间的差距仅占这两个差距的50%。

所以,为了减少一点,非重用的上下文更快,因为当您创建上下文时,它知道这些页面是空的,并且没有其他人引用这些页面来强制它们在写入时被复制他们。当您重复使用上下文时,页面由其他人(您创建的映像)引用,并且必须在第一次写入时复制,以便在上下文的状态更改时保留映像的状态。

您可以通过在调试器中逐步查看进程的虚拟内存映射来进一步探索这里发生的情况。 vmmap是有用的工具。

实际上,您应该每次都可以创建一个新的CGContext。

总结

以上是内存溢出为你收集整理的objective-c – 重用一个导致奇怪性能损失的CGContext全部内容,希望文章能够帮你解决objective-c – 重用一个导致奇怪性能损失的CGContext所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1037835.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存