C# 优化XNA上的颜色操作

C# 优化XNA上的颜色操作,c#,optimization,profiling,xna,C#,Optimization,Profiling,Xna,我正在分析我的简单2D XNA游戏。我发现整个运行时间的4%是由两种颜色相加的简单操作占用的,其中一种颜色首先乘以float 我需要每帧调用这个方法2000次(对于地图上的每个瓷砖),这使得XNA的60 fps每秒调用120000次。即使是单次呼叫的最小提升也会带来巨大的速度影响。然而,我不知道如何才能使这更有效 private void DoColorCalcs(float factor, Color color) { int mul = (int)Math.M

我正在分析我的简单2D XNA游戏。我发现整个运行时间的4%是由两种颜色相加的简单操作占用的,其中一种颜色首先乘以float

我需要每帧调用这个方法2000次(对于地图上的每个瓷砖),这使得XNA的60 fps每秒调用120000次。即使是单次呼叫的最小提升也会带来巨大的速度影响。然而,我不知道如何才能使这更有效

    private void DoColorCalcs(float factor, Color color)
    {
        int mul = (int)Math.Max(Math.Min(factor * 255.0, 255.0), 0.0);
        tile.Color = new Color(
            (byte)Math.Min(tile.Color.R + (color.R * mul / 255), 255),
            (byte)Math.Min(tile.Color.G + (color.G * mul / 255), 255),
            (byte)Math.Min(tile.Color.B + (color.B * mul / 255), 255));

    }
编辑:根据Michael Stum的建议:

    private void DoColorCalcs(float factor, Color color)
    {
        factor= (float)Math.Max(factor, 0.0);
        tile.Color = new Color(
            (byte)Math.Min(tile.Color.R + (color.R * factor), 255),
            (byte)Math.Min(tile.Color.G + (color.G * factor), 255),
            (byte)Math.Min(tile.Color.B + (color.B * factor), 255));
    }

这将时间使用从4%降低到2.5%

明显的改进是在计算
mul
时加入除法运算(/255),将除法从3减少到单个除法:

private void DoColorCalcs(float factor, Color color)
{
    float mul = Math.Max(Math.Min(factor * 255.0f, 255.0f), 0.0f) / 255f; 
    tile.Color = new Color(
        (byte)Math.Min(tile.Color.R + (color.R * mul), 255),
        (byte)Math.Min(tile.Color.G + (color.G * mul), 255),
        (byte)Math.Min(tile.Color.B + (color.B * mul), 255));
}
也就是说,由于您正在替换tile.Color,实际上替换它而不是覆盖它可能会更快(尽管我会对此进行分析,看看是否有帮助):


这会阻止alpha通道的重新计算,并可能会稍微减少指令量。

我的第一个问题是,为什么是浮点?如果只是缩放颜色使其褪色,则不需要太多的精度。例如:

int factorTimes256;
tile.Color.R = Math.Max(255, tile.Color.R + (color.R * factorTimes256) / 256);
// same for G and B
换句话说,将因子表示为0到256之间的整数,并对整数进行所有计算。您不需要比8位更高的精度,因为结果只有8位

我的第二个问题是,你说你在这个代码中从4%到2.5%了吗? 那太小了。 使用只对程序计数器进行检测或采样的分析器的人通常对这些小的改进感到满意。
我打赌你还有其他事情要做,需要花很多时间,你可以攻击

你要找的词是“优化”,而不是“优化”。)这听起来像是很多人在呼吁一个简单的2D游戏。你不能改变整个算法吗?例如,通过缓存结果或避免每帧都执行所有操作?我需要重新计算瓷砖的动态灯光(我的灯光模型包括灯光闪烁,它以Sin(时间)*0.1的速率改变灯光强度,对于每帧中的给定瓷砖),您需要使其更高效吗?当前的性能实际上是一个问题吗?你刚才说它只需要总执行时间的4%。这意味着你的“巨大”速度影响最多将是4%。这意味着你的应用程序可能以每秒62.4帧的速度运行,而不是以每秒60帧的速度运行。这真的值得付出努力吗?你可以尝试将你的瓷砖分成2(4,8)组,并创建几个线程-每个线程计算一个瓷砖组的颜色。因此,您可以使用处理器提供的所有内核。(int)Math.Max(Math.Min(factor*255.0,255.0),0.0)/255在大多数情况下将得到0。所以这没有帮助。同意Simon Ottenhaus的观点-你将整数0..255除以255,得到254个零和单值“1”,啊,我忘了-我试图通过设置它的变量来代替创建新的颜色对象。这需要一点“糟糕的方法”,因为我不得不将tile.Color从访问器类型更改为变量。但它仍然没有速度影响(测试和四舍五入结果为0,1 fps),你不能将mul改为浮点吗?或者这会不会太不准确?你可以这样做,但你必须让mul成为一个浮点数。因为你在其他的计算中都在做基于浮点数的数学运算,所以应该会有一点速度提升。
int factorTimes256;
tile.Color.R = Math.Max(255, tile.Color.R + (color.R * factorTimes256) / 256);
// same for G and B