实例介绍
dave-hillier:Basic implementation of Disruptor for Unity3d源码下载
Disruptor为Unity3d的基础、自包含实现,仅支持单生产者/单消费者模式。只在x86平台上进行了测试,由于Mono的bug,该实现在Unity 5.5之前的iOS和Android上无法工作。
使用方法:
将RingBuffer.cs复制到您的Unity项目的assets文件夹(或子文件夹)中,并使用泛型RingBuffer类。
例如:
var buffer = new RingBuffer<int>(8);
for (int i = 1; i < 6; ++i)
buffer.Enqueue(i);
for (int i = 1; i < 6; ++i)
buffer.Dequeue();
动机:
Unity3d是一个内嵌Mono的游戏引擎。Unity内部的Mono版本非常旧,没有SGen收集器,使用的是Boehm GC,其性能不佳。在Unity项目工作时,我发现自己需要一个队列来在线程间发送消息。当前版本的Mono包含了ConcurrentQueue的实现。我的游戏非常频繁地使用队列。当我想发送消息时,它会被加入队列,然后由另一个线程出队、序列化并发送。通过性能分析,我看到队列似乎是偶尔帧率下降的原因,因为每发送一个消息就会进行一次内存分配。这些分配可以随时导致GC停顿,但有时候它并不明显出现在性能分析器上(例如,性能分析器会显示长时间的分配本身和总内存使用量的减少)。
我想用一个没有额外分配开销的东西来替换ConcurrentQueue。循环缓冲区是一种固定大小的数据结构,可以在这种情况下使用。寻找现有实现时,我记得Disruptor;一个高性能的无锁队列。Disruptor有许多好的特性,但在我的案例中,我只关心没有分配的特性。
存在一个.Net的Disruptor移植版本,但它是针对.Net 4的,Unity不支持,并且实际上它会进行一些分配。我不想花时间进行移植,而且我的用例非常简单。我不需要大部分功能。
我实现了一个非常简单、自包含的版本,使用了实现中关键的volatile long。它旨在自包含;只需将源代码放入项目中即可。此项目不旨在与disruptor-net的功能竞争,而是提供一个易于使用的队列。如果您需要一个功能齐全的Disruptor库,那么您应该移植或查看forks,以防有人已经完成了。
基准测试:
我为我的单生产者/单消费者RingBuffer创建了一个基准测试。每一帧都会将一批随机整数排队。这些值被另一个线程出队并丢弃。
此基准测试不是作为示例用例或性能取证的意图,但允许我对分配进行性能分析。
并发队列注意:
- 黄色尖峰代表GC花费的时间。
- 所有帧的时间都超过5ms,有些帧的时间超过16ms。
RingBuffer注意:
- 没有黄色GC尖峰
- 大多数帧的时间都在5ms以下,没有帧的时间超过16ms。
【实例截图】

【核心代码】
标签:
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论