这一篇主要围绕一些代码洁癖问题进行观察测试,在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储存计算完事了。