mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
Add fast math optimization
This commit is contained in:
parent
55b0ecb487
commit
ab4c0f0361
3 changed files with 216 additions and 41 deletions
|
|
@ -444,6 +444,172 @@ void ExprEvalState::setStringVariable(const char *val)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum class FloatOperation
|
||||||
|
{
|
||||||
|
Add,
|
||||||
|
Sub,
|
||||||
|
Mul,
|
||||||
|
Div,
|
||||||
|
|
||||||
|
LT,
|
||||||
|
LE,
|
||||||
|
GR,
|
||||||
|
GE,
|
||||||
|
EQ,
|
||||||
|
NE
|
||||||
|
};
|
||||||
|
|
||||||
|
template<FloatOperation Op>
|
||||||
|
TORQUE_FORCEINLINE void doFloatMathOperation()
|
||||||
|
{
|
||||||
|
ConsoleValue& a = stack[_STK];
|
||||||
|
ConsoleValue& b = stack[_STK - 1];
|
||||||
|
|
||||||
|
S32 fastIf = (a.getType() == ConsoleValueType::cvFloat) & (b.getType() == ConsoleValueType::cvFloat);
|
||||||
|
if (fastIf)
|
||||||
|
{
|
||||||
|
// Arithmetic
|
||||||
|
if constexpr (Op == FloatOperation::Add)
|
||||||
|
stack[_STK - 1].setFastFloat(a.getFastFloat() + b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::Sub)
|
||||||
|
stack[_STK - 1].setFastFloat(a.getFastFloat() - b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::Mul)
|
||||||
|
stack[_STK - 1].setFastFloat(a.getFastFloat() * b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::Div)
|
||||||
|
stack[_STK - 1].setFastFloat(a.getFastFloat() / b.getFastFloat());
|
||||||
|
|
||||||
|
// Logical
|
||||||
|
if constexpr (Op == FloatOperation::LT)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() < b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::LE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() <= b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::GR)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() > b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::GE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() >= b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::EQ)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() == b.getFastFloat());
|
||||||
|
if constexpr (Op == FloatOperation::NE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastFloat() != b.getFastFloat());
|
||||||
|
|
||||||
|
_STK--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doSlowMathOp<Op>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<FloatOperation Op>
|
||||||
|
TORQUE_NOINLINE void doSlowMathOp()
|
||||||
|
{
|
||||||
|
ConsoleValue& a = stack[_STK];
|
||||||
|
ConsoleValue& b = stack[_STK - 1];
|
||||||
|
|
||||||
|
// Arithmetic
|
||||||
|
if constexpr (Op == FloatOperation::Add)
|
||||||
|
stack[_STK - 1].setFloat(a.getFloat() + b.getFloat());
|
||||||
|
else if constexpr (Op == FloatOperation::Sub)
|
||||||
|
stack[_STK - 1].setFloat(a.getFloat() - b.getFloat());
|
||||||
|
else if constexpr (Op == FloatOperation::Mul)
|
||||||
|
stack[_STK - 1].setFloat(a.getFloat() * b.getFloat());
|
||||||
|
else if constexpr (Op == FloatOperation::Div)
|
||||||
|
stack[_STK - 1].setFloat(a.getFloat() / b.getFloat());
|
||||||
|
|
||||||
|
// Logical
|
||||||
|
if constexpr (Op == FloatOperation::LT)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() < b.getFloat());
|
||||||
|
if constexpr (Op == FloatOperation::LE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() <= b.getFloat());
|
||||||
|
if constexpr (Op == FloatOperation::GR)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() > b.getFloat());
|
||||||
|
if constexpr (Op == FloatOperation::GE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() >= b.getFloat());
|
||||||
|
if constexpr (Op == FloatOperation::EQ)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() == b.getFloat());
|
||||||
|
if constexpr (Op == FloatOperation::NE)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFloat() != b.getFloat());
|
||||||
|
|
||||||
|
_STK--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
enum class IntegerOperation
|
||||||
|
{
|
||||||
|
BitAnd,
|
||||||
|
BitOr,
|
||||||
|
Xor,
|
||||||
|
LShift,
|
||||||
|
RShift,
|
||||||
|
|
||||||
|
LogicalAnd,
|
||||||
|
LogicalOr
|
||||||
|
};
|
||||||
|
|
||||||
|
template<IntegerOperation Op>
|
||||||
|
TORQUE_FORCEINLINE void doIntOperation()
|
||||||
|
{
|
||||||
|
ConsoleValue& a = stack[_STK];
|
||||||
|
ConsoleValue& b = stack[_STK - 1];
|
||||||
|
|
||||||
|
if (a.isNumberType() && b.isNumberType())
|
||||||
|
{
|
||||||
|
// Bitwise Op
|
||||||
|
if constexpr (Op == IntegerOperation::BitAnd)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() & b.getFastInt());
|
||||||
|
if constexpr (Op == IntegerOperation::BitOr)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() | b.getFastInt());
|
||||||
|
if constexpr (Op == IntegerOperation::Xor)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() ^ b.getFastInt());
|
||||||
|
if constexpr (Op == IntegerOperation::LShift)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() << b.getFastInt());
|
||||||
|
if constexpr (Op == IntegerOperation::RShift)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() >> b.getFastInt());
|
||||||
|
|
||||||
|
// Logical Op
|
||||||
|
if constexpr (Op == IntegerOperation::LogicalAnd)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() && b.getFastInt());
|
||||||
|
if constexpr (Op == IntegerOperation::LogicalOr)
|
||||||
|
stack[_STK - 1].setFastInt(a.getFastInt() || b.getFastInt());
|
||||||
|
|
||||||
|
_STK--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
doSlowIntegerOp<Op>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<IntegerOperation Op>
|
||||||
|
TORQUE_NOINLINE void doSlowIntegerOp()
|
||||||
|
{
|
||||||
|
ConsoleValue& a = stack[_STK];
|
||||||
|
ConsoleValue& b = stack[_STK - 1];
|
||||||
|
|
||||||
|
// Bitwise Op
|
||||||
|
if constexpr (Op == IntegerOperation::BitAnd)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() & b.getInt());
|
||||||
|
if constexpr (Op == IntegerOperation::BitOr)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() | b.getInt());
|
||||||
|
if constexpr (Op == IntegerOperation::Xor)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() ^ b.getInt());
|
||||||
|
if constexpr (Op == IntegerOperation::LShift)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() << b.getInt());
|
||||||
|
if constexpr (Op == IntegerOperation::RShift)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() >> b.getInt());
|
||||||
|
|
||||||
|
// Logical Op
|
||||||
|
if constexpr (Op == IntegerOperation::LogicalAnd)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() && b.getInt());
|
||||||
|
if constexpr (Op == IntegerOperation::LogicalOr)
|
||||||
|
stack[_STK - 1].setInt(a.getInt() || b.getInt());
|
||||||
|
|
||||||
|
_STK--;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
U32 gExecCount = 0;
|
U32 gExecCount = 0;
|
||||||
ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||||
{
|
{
|
||||||
|
|
@ -1151,56 +1317,39 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
||||||
goto execFinished;
|
goto execFinished;
|
||||||
|
|
||||||
case OP_CMPEQ:
|
case OP_CMPEQ:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() == stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::EQ>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CMPGR:
|
case OP_CMPGR:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() > stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::GR>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CMPGE:
|
case OP_CMPGE:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() >= stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::GE>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CMPLT:
|
case OP_CMPLT:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() < stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::LT>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CMPLE:
|
case OP_CMPLE:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() <= stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::LE>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_CMPNE:
|
case OP_CMPNE:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getFloat() != stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::NE>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_XOR:
|
case OP_XOR:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() ^ stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::Xor>();
|
||||||
_STK--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_MOD:
|
|
||||||
if (stack[_STK - 1].getInt() != 0)
|
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() % stack[_STK - 1].getInt());
|
|
||||||
else
|
|
||||||
stack[_STK - 1].setInt(0);
|
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_BITAND:
|
case OP_BITAND:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() & stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::BitAnd>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_BITOR:
|
case OP_BITOR:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() | stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::BitOr>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_NOT:
|
case OP_NOT:
|
||||||
|
|
@ -1216,44 +1365,47 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_SHR:
|
case OP_SHR:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() >> stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::RShift>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_SHL:
|
case OP_SHL:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() << stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::LShift>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_AND:
|
case OP_AND:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() && stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::LogicalAnd>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_OR:
|
case OP_OR:
|
||||||
stack[_STK - 1].setInt(stack[_STK].getInt() || stack[_STK - 1].getInt());
|
doIntOperation<IntegerOperation::LogicalOr>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_ADD:
|
case OP_ADD:
|
||||||
stack[_STK - 1].setFloat(stack[_STK].getFloat() + stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::Add>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_SUB:
|
case OP_SUB:
|
||||||
stack[_STK - 1].setFloat(stack[_STK].getFloat() - stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::Sub>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_MUL:
|
case OP_MUL:
|
||||||
stack[_STK - 1].setFloat(stack[_STK].getFloat() * stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::Mul>();
|
||||||
_STK--;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_DIV:
|
case OP_DIV:
|
||||||
stack[_STK - 1].setFloat(stack[_STK].getFloat() / stack[_STK - 1].getFloat());
|
doFloatMathOperation<FloatOperation::Div>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OP_MOD:
|
||||||
|
{
|
||||||
|
S64 divisor = stack[_STK - 1].getInt();
|
||||||
|
if (divisor != 0)
|
||||||
|
stack[_STK - 1].setInt(stack[_STK].getInt() % divisor);
|
||||||
|
else
|
||||||
|
stack[_STK - 1].setInt(0);
|
||||||
_STK--;
|
_STK--;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case OP_NEG:
|
case OP_NEG:
|
||||||
stack[_STK].setFloat(-stack[_STK].getFloat());
|
stack[_STK].setFloat(-stack[_STK].getFloat());
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,28 @@ public:
|
||||||
return type >= ConsoleValueType::cvConsoleValueType;
|
return type >= ConsoleValueType::cvConsoleValueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setFastFloat(F64 flt)
|
||||||
|
{
|
||||||
|
type = ConsoleValueType::cvFloat;
|
||||||
|
f = flt;
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE F64 getFastFloat() const
|
||||||
|
{
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE void setFastInt(S64 flt)
|
||||||
|
{
|
||||||
|
type = ConsoleValueType::cvInteger;
|
||||||
|
i = flt;
|
||||||
|
}
|
||||||
|
|
||||||
|
TORQUE_FORCEINLINE S64 getFastInt() const
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ typedef unsigned _int64 U64;
|
||||||
#pragma warning(disable: 4291)
|
#pragma warning(disable: 4291)
|
||||||
|
|
||||||
#define TORQUE_FORCEINLINE __forceinline
|
#define TORQUE_FORCEINLINE __forceinline
|
||||||
|
#define TORQUE_NOINLINE __declspec(noinline)
|
||||||
|
|
||||||
#if __cplusplus >= 201703L
|
#if __cplusplus >= 201703L
|
||||||
#define TORQUE_CASE_FALLTHROUGH [[fallthrough]];
|
#define TORQUE_CASE_FALLTHROUGH [[fallthrough]];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue