开发手札:图形中int和float运算性能问题

       这一篇主要围绕一些代码洁癖问题进行观察测试,在gameplay和shader开发中,int/float等数值类型的乘除运算属于很常见的,关于其性能和耗时也有区别(这点我看了百度google也没个明确的说法),当然我们如果只是写普通代码,其实不用过于在意此这些问题。

       如果是进行着色器开发,我们还是要明了一下比较好。在着色器开发中,片段函数中代码的计算运算次数是很庞大的,以千万/亿为单位,所以我们需要明确int/float/half/fixed的乘除运算性能问题,下面我们来测试一下,因为shader使用c编写,那么我们就使用c来测试。

       如下,我单纯的使用主线程进行int和float的运算,查看运算时间的差异(注意:1.我不使用线程是因为线程有资源优先级的问题,我看百度上很多人用多线程测试,这种是错误的 2.同时我不使用数值类型强转,避免其他性能消耗影响 3.最后我使用10和3这种除不尽的数值为了普适化),那么贴代码跑起来吧,目标100000000000次运算。

#include "stdafx.h"
#include<thread>
#include<Windows.h>
#include<string.h>

using namespace std;

const int COUNT = 100000000000;

DWORD crtTime;

void PrintCrtTime()
{
	crtTime = GetTickCount();
	printf("\n");
	printf("当前时间:%d\n", crtTime);
}

void PrintElapseTime(string method)
{
	DWORD crt = GetTickCount();
	printf("执行方法:%s 当前时间:%d\n", method.c_str(), crt);
	printf("执行方法:%s 使用时间:%d\n", method.c_str(), crt - crtTime);
	printf("\n");
}

void IntMultiplyInt()
{
	PrintCrtTime();
	int count = COUNT;
	int a = 10;
	int b = 3;
	int c;
	while (count > 0)
	{
		a * b;
		//c = (int)(a * b);
		count--;
	}
	PrintElapseTime("int乘int");
}

void IntMultiplyFloat()
{
	PrintCrtTime();
	int count = COUNT;
	int a = 10;
	float b = 3.0;
	int c;
	while (count > 0)
	{
		a * b;
		//c = (int)(a * b);
		count--;
	}
	PrintElapseTime("int乘float");
}

void FloatMultiplyFloat()
{
	PrintCrtTime();
	int count = COUNT;
	float a = 10.0;
	float b = 3.0;
	int c;
	while (count > 0)
	{
		a * b;
		//c = (int)(a * b);
		count--;
	}
	PrintElapseTime("float乘float");
}

void IntDivisionInt()
{
	PrintCrtTime();
	int count = COUNT;
	int a = 10;
	int b = 3;
	int c;
	while (count > 0)
	{
		a / b;
		//c = (int)(a / b);
		count--;
	}
	PrintElapseTime("int除int");
}

void IntDivisionFloat()
{
	PrintCrtTime();
	int count = COUNT;
	int a = 10;
	float b = 3.0;
	int c;
	while (count > 0)
	{
		a / b;
		//c = (int)(a / b);
		count--;
	}
	PrintElapseTime("int除float");
}

void FloatDivisionFloat()
{
	PrintCrtTime();
	int count = COUNT;
	float a = 10.0;
	float b = 3.0;
	int c;
	while (count > 0)
	{
		a / b;
		//c = (int)(a / b);
		count--;
	}
	PrintElapseTime("float除float");
}

int main()
{
	IntMultiplyInt();
	IntMultiplyFloat();
	FloatMultiplyFloat();

	IntDivisionInt();
	IntDivisionFloat();
	FloatDivisionFloat();

	return 0;
}

        运算结果如下:

 

       可以看得出来,int除int消耗时间最多,但是从整体看来,我认为几乎没有区别,所以在100000000000次运算下,我们可以说单纯的int/float乘除,性能一样。

       但是,我们使用代码进行数值运算了,肯定要得到结果的,那么就存在中间值之间的转换问题,接下来我们使用int c储存结果值,看下100000000000次运算的性能差别,如下:

      

       结果:

      

       可以看得出来以下三点:

       1.int除float消耗性能最高

       2.乘法除法运算中,不同类型相乘除最耗时

       3.都使用float运算,耗时最少,性能最高

       当然如果我们把c改成float呢?如下:

      

       结果:

      

       看得出来不同类型运算依旧是最耗时的,同时float类型不论做乘除运算都没什么性能差距。

       那么,我们以后怎么写代码合适呢?或者说我们可以抛弃掉哪些无所谓的写法操作呢?我认为有以下三点:

       1.尽量使用同类型进行运算。打个比方,我们需要对纹理或者分辨率进行运算,因为纹理和分辨率都是int型,那么我们可以使用float进行储存后,再进行缩放/比例计算等运算。

       2.不用在意float的乘除问题,也就是说说不用将10.0f/3.0f改成10.0f*0.333333f等,这样不仅没有增加性能,还会造成多次复合运算后的精度不准确,我看很多主程写代码甚至都牺牲精确性都要将float的除法改成乘法,脾气暴躁的看到刚毕业的实习生这么写,还要上去骂两句,你自己要做测试,不要人云亦云。

      3.float就是比int进行计算快,我看很多人都潜意识觉得float的使用更消耗性能,好多时候都会强转成int,没必要,不仅运算更慢,还不精确。就用float储存计算完事了。

      

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值