我正在寻找一种非常有效和准确的方法来确定位图的平均RGB值。我目前有一种带有逐位像素的位锁的方法,在30Hz时大约占我CPU的25%。
通过查看每三个像素,我设法将其降低到约15%,但我相信有更好的方法。我也尝试将计算转移到GPU(Nvidia CUDA),但由于我在GPU编程方面经验不足,所以只花了更长的时间。
我已经考虑过应用模糊等问题,但这并不会减少像素数量,因此不会影响计算。
我想听听你对这个有趣主题的想法。
答案 0 :(得分:1)
您可以使用内在函数开发一个c ++ dll,使用SIMD优化/矢量化代码进行相同的计算。那么即使在相同的使用百分比下,cpu使用也会更有效。处理非对齐标题部分,然后使用更快的内部函数处理剩余的对齐部分。
如果这还不够,请尝试将图像的一半甚至四分之一移动到GPU,因为pci-e是瓶颈。
流水线操作还有助于隐藏复制到gpu的一些延迟,但使用更多CPU但更快完成,因此使用的总周期更少。
如果位图已经在cpu缓存中,它应该能够在GPU处理“映射”内存块(另一个位图或相同位图的一部分)时同时处理它,而不会出现瓶颈RAM。如果要传输数据,请不要复制到GPU。让GPU使用适当的访问函数或标志将其映射到自己的控制器上。
“映射”的起始点可能是位图字节数组的4096个寻址元素的第一个倍数。
如果你有一个集成的gpu,请尝试使用opencl,因为它更接近RAM。
对于纯C#解决方案,尝试多个累加器以更好地使用cpu管道。在不安全的环境中使用它们。通过int或long读取,而不是字节。然后使用bithacks处理它,除非C#已经在进行矢量化。
扫描平均值不使用乘法单位。因此,您可以使用一些交错代码或执行异步来增加内容。也许你可以同时混合其他一些位图?
c[i]=a[i]+b[i]
与简单的C#one-liner相比,使用完全优化的gpgpu方法,快18倍。我正在使用Visual Studio 2015 Community Edition(项目处于发布模式且64位目标)。使用Intel HD-400 iGPU(600MHz)和C3060(1.6GHz)(单通道RAM),这是一款低端笔记本电脑,CPU使用率为50%而不是纯粹C#的70%。