我正在使用ffmpeg编写视频播放器(仅限Windows,Visual Studio 2015,64位编译)。 使用常见视频(最高4K @ 30FPS),效果非常好。但凭借我的最大目标 - 4K @ 60FPS,它失败了。解码仍然足够快,但是当谈到YUV / BGRA转换时,它的速度根本不够快,即使它是在16个线程中完成的(16/32核心机器上每帧一个线程)。
因此,作为第一个对策,我跳过了一些帧的转换,并以这种方式获得了~40的稳定帧速率。比较Concurrency Visualizer中的两个版本,我发现了一个奇怪的问题,我不知道原因。
这是frameskip版本的图片: 你看到转换非常快(平均约为35毫秒) 因此,当使用多个线程时,它也应该足够快到60FPS,但它不是!
非frameskip版本的图像显示了原因: 单帧的转换速度比以前慢了十倍(平均约为350毫秒)。现在,许多核心上的繁重工作量当然会导致每个核心的轻微减速,因为涡轮增压减少 - 比方说10%或20%。但绝不会出现~1000%的极端放缓。
有趣的细节是,非frameskip版本的堆栈跟踪显示了一些我不太了解的系统活动 - 从ntoskrnl.exe!KiPageFault+0x373
开始。没有例外,其他错误消息等 - 它变得非常慢。
编辑:一位同事刚刚告诉我,这看起来像内存问题乍一看已分页内存 - 但我的内存利用率很低(低于1GB,超过20GB免费)
有人能告诉我是什么原因引起的吗?
答案 0 :(得分:1)
这可能太旧了,无法使用,但仅作记录:
可能正在发生的事情是您在多个线程中一次又一次地分配4k帧。 Windows分配器确实不喜欢这种访问模式。
malloc本身不会显示在事件探查器中,因为只有在实际访问内存时,操作系统才会获取页面。它显示为ntoskrnl.exe!KiPageFault
,并归因于该函数首先访问新内存。
解决方案包括: