-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance optimization for StreamSafeCudaAllocator #40718
Performance optimization for StreamSafeCudaAllocator #40718
Conversation
✅ This PR's description meets the template requirements! |
你的PR提交成功,感谢你对开源项目的贡献! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
PR types
Performance optimization
PR changes
Others
Describe
PR #40460 对Profiler的RecordEvent操作进行了性能优化,优化之后在AutoGrowth策略下开启StreamSafeCUDAAllocator,即使是不使用多stream功能,显存分配操作也仍有约2倍的性能开销增加(因StreamSafeCUDAAllocator和AutoGrowthBestFitAllocatorh中均有RecordEvent打点操作,相关优化同时对AutoGrowth也生效,不止针对StreamSafeCUDAAllocaror)。
显存分配上增加的开销,主要来自延迟创建Allocator引入的读写锁、从DeviceContextPool中获取默认stream、ProcessUnfreedAllocations为了多线程安全而引入的自旋锁,以及新包一层StreamSafeCUDAAllocation的堆内存分配(new操作)和构造等。
因对目前实际应用的大多数模型来说,跨stream的显存操作占比并不高,本PR尝试对StreamSafeCUDAAllocator在无跨stream使用场景下的显存分配性能进行优化,目标是使得对模型中没有指定stream(即默认使用DeviceContex中的stream)、且后续未进行跨stream显存使用的相关Allocation分配操作,相比未支持多stream之前的单stream显存分配,尽量不引入较多的性能开销。
针对StreamSafeCUDAAllocator的显存分配操作,本PR进行以下两点优化:
本PR使得StreamSafeCUDAAllocatora开启前后,对默认stream的显存分配操作开销增加从约2倍降低到约55%。
通过以下代码进行性能测试:
在本PR优化之后,执行上述代码,测试开启多stream前后性能对比如下:
开启多stream之前:
开启多stream之后:
此时显存分配操作(AllocFacade::Alloc)的耗时只从2.14秒增加到3.31秒,增加了1.17秒,约55%开销占比。
剩余的开销主要来自以下部分:
在显存回收方面,主要开销来自StreamSafeCUDAAllocation结构体的析构和释放,此外还有额外一次deleter的调用和CanBeFree的判断等,但后者开销占比并不大,本PR未对显存回收操作的性能开销进行优化。
可以看出,优化之后剩余的性能开销主要都来自StreamSafeCUDAAllocation的内存分配、构造和析构,这部分是Allocator层层包裹的装饰者设计模式导致的,除非整体推翻这种设计模式,否则每新加一层新功能的Allocator就不可避免地需要引入新一层的构造和析构开销,没有更大的优化空间。