Skip to content

Commit

Permalink
For issue #35.
Browse files Browse the repository at this point in the history
Fixes the unit test values for __core2__ and __k8__. Adds unit test code specific to the new GetMaxSeparation4x4 function. Updates the benchmark README info.
  • Loading branch information
louis-langholtz committed Aug 9, 2017
1 parent 0b7b64a commit 0599bd9
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 43 deletions.
90 changes: 59 additions & 31 deletions Benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,67 @@ Coming.

## Sample Output

Note that the following times are for running the named benchmarks which may have way more overhead than their names suggests. What's telling however from this output, is that operations like sine and cosine take significantly longer than square root or division.
Note that the following times are for running the named benchmarks which may have way more overhead than their names suggests. What's seemingly significant from this output however, is that operations like sine and cosine take significantly longer than square root or division.

```sh
Run on (8 X 2600 MHz CPU s)
2017-07-30 23:55:17
------------------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------------------
TwoRandValues 13 ns 13 ns 51577916
FloatAddition 14 ns 14 ns 51504672
FloatMultiplication 13 ns 13 ns 50828874
FloatDivision 14 ns 14 ns 51230633
FloatSqrt 14 ns 14 ns 51709746
FloatSin 36 ns 36 ns 19214616
FloatCos 38 ns 38 ns 18015282
DoubleAddition 14 ns 14 ns 51263649
DoubleMultiplication 14 ns 14 ns 50961349
DoubleDivision 17 ns 17 ns 41517402
DoubleSqrt 17 ns 17 ns 41396113
DoubleSin 47 ns 47 ns 14996936
DoubleCos 46 ns 46 ns 15167701
LengthSquaredViaDotProduct 14 ns 14 ns 51132587
BM_GetLengthSquared 14 ns 14 ns 51320777
BM_GetLength 14 ns 14 ns 52137643
UnitVectorFromVec2 18 ns 18 ns 39641415
FourRandValues 27 ns 27 ns 26449229
DotProduct 27 ns 27 ns 26235013
CrossProduct 27 ns 27 ns 25916999
ConstructAndAssignVC 31 ns 31 ns 22595296
SolveVC 41 ns 41 ns 16685299
GetMaxSeparation 104 ns 103 ns 6795655
ManifoldForTwoSquares1 175 ns 175 ns 3920075
ManifoldForTwoSquares2 198 ns 198 ns 3505100
TilesComesToRest 54129850 ns 54124818 ns 11
2017-08-08 20:51:19
--------------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------------
FloatAdd 2 ns 2 ns 368982294
FloatMult 2 ns 2 ns 366233291
FloatDiv 2 ns 2 ns 358505544
FloatSqrt 2 ns 2 ns 382018915
FloatSin 7 ns 7 ns 113156916
FloatCos 6 ns 6 ns 110023105
FloatAtan2 7 ns 7 ns 99072960
DotProduct 2 ns 2 ns 373072680
CrossProduct 2 ns 2 ns 363119508
LengthSquaredViaDotProduct 2 ns 2 ns 351751724
GetLengthSquared 2 ns 2 ns 379617779
GetLength 2 ns 2 ns 384497078
hypot 4 ns 4 ns 175868792
UnitVectorFromVector 2 ns 2 ns 294130005
UnitVectorFromVectorAndBack 2 ns 2 ns 297693724
UnitVecFromAngle 8 ns 8 ns 80838877
TwoRandValues 13 ns 13 ns 54730686
FloatAddTwoRand 13 ns 13 ns 54026102
FloatMultTwoRand 13 ns 13 ns 53356505
FloatDivTwoRand 13 ns 13 ns 53571702
FloatSqrtTwoRand 13 ns 13 ns 53826280
FloatSinTwoRand 36 ns 36 ns 18716828
FloatCosTwoRand 35 ns 35 ns 20197240
FloatAtan2TwoRand 28 ns 28 ns 25564146
DoubleAddTwoRand 14 ns 14 ns 53771288
DoubleMultTwoRand 14 ns 14 ns 51642604
DoubleDivTwoRand 18 ns 17 ns 40536706
DoubleSqrtTwoRand 18 ns 18 ns 38975718
DoubleSinTwoRand 49 ns 49 ns 14750226
DoubleCosTwoRand 48 ns 48 ns 14213313
DoubleAtan2TwoRand 69 ns 69 ns 10425199
LengthSquaredViaDotProductTwoRand 14 ns 14 ns 50312657
GetLengthSquaredTwoRand 15 ns 15 ns 48167237
GetLengthTwoRand 14 ns 14 ns 50834780
hypotTwoRand 15 ns 15 ns 44679900
UnitVectorFromVectorTwoRand 17 ns 17 ns 43387444
UnitVectorFromVectorAndBackTwoRand 17 ns 17 ns 41706884
FourRandValues 28 ns 28 ns 24096717
DotProductFourRand 29 ns 29 ns 24427097
CrossProductFourRand 29 ns 29 ns 24291133
ConstructAndAssignVC 33 ns 33 ns 20916126
SolveVC 44 ns 44 ns 15413987
MaxSepBetweenAbsRectangles 74 ns 74 ns 9816020
MaxSepBetweenRel4x4 80 ns 80 ns 8796069
MaxSepBetweenRel2_4x4 82 ns 82 ns 8408913
MaxSepBetweenRelRectanglesNoStop 104 ns 104 ns 6918432
MaxSepBetweenRelRectangles2NoStop 103 ns 103 ns 6850119
MaxSepBetweenRelRectangles 104 ns 104 ns 6884275
MaxSepBetweenRelRectangles2 100 ns 100 ns 7195058
ManifoldForTwoSquares1 156 ns 155 ns 4617475
ManifoldForTwoSquares2 157 ns 157 ns 4675863
TilesComesToRest12 57637128 ns 57506769 ns 13
TilesComesToRest20 375657450 ns 375055500 ns 2
TilesComesToRest36 3974857636 ns 3973611000 ns 1
Program ended with exit code: 0
```
5 changes: 3 additions & 2 deletions PlayRho/Collision/Manifold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,16 +450,17 @@ Manifold playrho::CollideShapes(const DistanceProxy& shapeA, const Transformatio
}

const auto totalRadius = shapeA.GetVertexRadius() + shapeB.GetVertexRadius();
const auto do4x4 = (countA == 4) && (countB == 4);

const auto edgeSepA = (countA == 4 && countB ==4)?
const auto edgeSepA = do4x4?
::GetMaxSeparation4x4(shapeA, xfA, shapeB, xfB):
::GetMaxSeparation(shapeA, xfA, shapeB, xfB, totalRadius);
if (edgeSepA.separation > totalRadius)
{
return Manifold{};
}

const auto edgeSepB = (countA == 4 && countB ==4)?
const auto edgeSepB = do4x4?
::GetMaxSeparation4x4(shapeB, xfB, shapeA, xfA):
::GetMaxSeparation(shapeB, xfB, shapeA, xfA, totalRadius);
if (edgeSepB.separation > totalRadius)
Expand Down
118 changes: 118 additions & 0 deletions UnitTests/CollideShapes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "gtest/gtest.h"
#include <PlayRho/Collision/Manifold.hpp>
#include <PlayRho/Collision/WorldManifold.hpp>
#include <PlayRho/Collision/ShapeSeparation.hpp>
#include <PlayRho/Collision/Shapes/DiskShape.hpp>
#include <PlayRho/Collision/Shapes/PolygonShape.hpp>
#include <PlayRho/Collision/Shapes/EdgeShape.hpp>
Expand Down Expand Up @@ -502,6 +503,123 @@ TEST(CollideShapes, IdenticalHorizontalTouchingSquares)
EXPECT_EQ(manifold.GetPoint(1).contactFeature.indexB, 3);
}

TEST(CollideShapes, GetMaxSeparationFreeFunction1)
{
const auto rot0 = Angle{Real{45.0f} * Degree};
const auto xfm0 = Transformation{Vec2{0, -2} * (Real(1) * Meter), UnitVec2::Get(rot0)}; // bottom
const auto xfm1 = Transformation{Vec2{0, +2} * (Real(1) * Meter), UnitVec2::GetRight()}; // top

const auto dim = Real(2) * Meter;
const auto shape0 = PolygonShape(dim, dim);
const auto shape1 = PolygonShape(dim, dim);
ASSERT_EQ(shape0.GetVertex(0), Vec2(+2, -2) * (Real(1) * Meter)); // bottom right
ASSERT_EQ(shape0.GetVertex(1), Vec2(+2, +2) * (Real(1) * Meter)); // top right
ASSERT_EQ(shape0.GetVertex(2), Vec2(-2, +2) * (Real(1) * Meter)); // top left
ASSERT_EQ(shape0.GetVertex(3), Vec2(-2, -2) * (Real(1) * Meter)); // bottom left

// Rotate square A and put it below square B.
// In ASCII art terms:
//
// +---4---+ <----- v1 of shape1
// | | |
// | B 3 |
// | | |
// | 2 |
// | | |
// | 1 |
// | /|\ |
// v3 ---> 2-1-0-1-2 <----- v0 of shape1
// / | \
// / 1 \
// / A | \
// + 2 + <----- v0 of shape0
// \ | /
// \ 3 /
// \ | /
// \ 4 /
// \|/
// + <----- v3 of shape0

const auto child0 = shape0.GetChild(0);
const auto child1 = shape1.GetChild(0);
const auto totalRadius = shape0.GetVertexRadius() + shape1.GetVertexRadius();

const auto maxSep01_4x4 = GetMaxSeparation4x4(child0, xfm0, child1, xfm1);
const auto maxSep10_4x4 = GetMaxSeparation4x4(child1, xfm1, child0, xfm0);
const auto maxSep01_NxN = GetMaxSeparation(child0, xfm0, child1, xfm1, totalRadius);
const auto maxSep10_NxN = GetMaxSeparation(child1, xfm1, child0, xfm0, totalRadius);

switch (sizeof(Real))
{
case 4:
EXPECT_EQ(maxSep01_4x4.index1, decltype(maxSep01_4x4.index1){0}); // v0 of shape0
EXPECT_EQ(maxSep01_4x4.index2, decltype(maxSep01_4x4.index1){3}); // v3 of shape1
break;
case 8:
EXPECT_EQ(maxSep01_4x4.index1, decltype(maxSep01_4x4.index1){1}); // v1 of shape0
EXPECT_EQ(maxSep01_4x4.index2, decltype(maxSep01_4x4.index1){0}); // v0 of shape1
break;
}
EXPECT_EQ(maxSep01_4x4.index1, maxSep01_NxN.index1);
EXPECT_EQ(maxSep01_4x4.index2, maxSep01_NxN.index2);
EXPECT_NEAR(static_cast<double>(Real(maxSep01_4x4.separation / Meter)),
-2.0, std::abs(-2.0) / 1000000.0);
EXPECT_NEAR(static_cast<double>(Real(maxSep01_4x4.separation / Meter)),
static_cast<double>(Real(maxSep01_NxN.separation / Meter)),
std::abs(static_cast<double>(Real(maxSep01_4x4.separation / Meter)) / 1000000.0));

EXPECT_EQ(maxSep10_4x4.index1, decltype(maxSep10_4x4.index1){3}); // v3 of shape1
EXPECT_EQ(maxSep10_4x4.index2, decltype(maxSep10_4x4.index1){1}); // v1 of shape0
EXPECT_EQ(maxSep10_4x4.index1, maxSep10_NxN.index1);
EXPECT_EQ(maxSep10_4x4.index2, maxSep10_NxN.index2);
EXPECT_NEAR(static_cast<double>(Real(maxSep10_4x4.separation / Meter)),
-0.82842707633972168, std::abs(-0.82842707633972168) / 1000000.0);
EXPECT_NEAR(static_cast<double>(Real(maxSep10_4x4.separation / Meter)),
static_cast<double>(Real(maxSep10_NxN.separation / Meter)),
std::abs(static_cast<double>(Real(maxSep10_4x4.separation / Meter)) / 1000000.0));
}

TEST(CollideShapes, GetMaxSeparationFreeFunction2)
{
const auto dim = Real(2) * Meter;
const auto shape = PolygonShape(dim, dim);
ASSERT_EQ(shape.GetVertex(0), Vec2(+2, -2) * (Real(1) * Meter)); // bottom right
ASSERT_EQ(shape.GetVertex(1), Vec2(+2, +2) * (Real(1) * Meter)); // top right
ASSERT_EQ(shape.GetVertex(2), Vec2(-2, +2) * (Real(1) * Meter)); // top left
ASSERT_EQ(shape.GetVertex(3), Vec2(-2, -2) * (Real(1) * Meter)); // bottom left

const auto xfm0 = Transformation{Vec2{0, -1} * (Real(1) * Meter), UnitVec2::GetRight()}; // bottom
const auto xfm1 = Transformation{Vec2{0, +1} * (Real(1) * Meter), UnitVec2::GetRight()}; // top
const auto totalRadius = shape.GetVertexRadius() * Real(2);

const auto child0 = shape.GetChild(0);
const auto maxSep01_4x4 = GetMaxSeparation4x4(child0, xfm0, child0, xfm1);
const auto maxSep10_4x4 = GetMaxSeparation4x4(child0, xfm1, child0, xfm0);
const auto maxSep01_NxN = GetMaxSeparation(child0, xfm0, child0, xfm1, totalRadius);
const auto maxSep10_NxN = GetMaxSeparation(child0, xfm1, child0, xfm0, totalRadius);


EXPECT_EQ(maxSep01_4x4.index1, decltype(maxSep01_4x4.index1){1}); // v0 of shape0
EXPECT_EQ(maxSep01_4x4.index1, maxSep01_NxN.index1);
EXPECT_EQ(maxSep01_4x4.index2, decltype(maxSep01_4x4.index1){0}); // v3 of shape1
EXPECT_EQ(maxSep01_4x4.index2, maxSep01_NxN.index2);
EXPECT_NEAR(static_cast<double>(Real(maxSep01_4x4.separation / Meter)),
-2.0, 0.0);
EXPECT_NEAR(static_cast<double>(Real(maxSep01_4x4.separation / Meter)),
static_cast<double>(Real(maxSep01_NxN.separation / Meter)),
std::abs(static_cast<double>(Real(maxSep01_4x4.separation / Meter)) / 1000000.0));

EXPECT_EQ(maxSep10_4x4.index1, decltype(maxSep10_4x4.index1){3}); // v3 of shape1
EXPECT_EQ(maxSep10_4x4.index1, maxSep10_NxN.index1);
EXPECT_EQ(maxSep10_4x4.index2, decltype(maxSep10_4x4.index1){1}); // v1 of shape0
EXPECT_EQ(maxSep10_4x4.index2, maxSep10_NxN.index2);
EXPECT_NEAR(static_cast<double>(Real(maxSep10_4x4.separation / Meter)),
-2.0, 0.0);
EXPECT_NEAR(static_cast<double>(Real(maxSep10_4x4.separation / Meter)),
static_cast<double>(Real(maxSep10_NxN.separation / Meter)),
std::abs(static_cast<double>(Real(maxSep10_4x4.separation / Meter)) / 1000000.0));
}

TEST(CollideShapes, SquareCornerTouchingSquareFaceAbove)
{
const auto dim = Real(2) * Meter;
Expand Down
34 changes: 24 additions & 10 deletions UnitTests/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2001,12 +2001,19 @@ TEST(World, TilesComesToRest)
{
case 4:
{
// From commit ee74290c17422ccbd6a73f07d6fd9abe960da84a onward:
EXPECT_EQ(numSteps, 1802ul);
EXPECT_EQ(sumRegPosIters, 36524ul);
EXPECT_EQ(sumRegVelIters, 46981ul);
EXPECT_EQ(sumToiPosIters, 44084ul);
EXPECT_EQ(sumToiVelIters, 114366ul);

// From commit 6b16f3722d5daac80ebaefd1dfda424939498dd4 onward:
EXPECT_EQ(numSteps, 1801ul);
EXPECT_EQ(sumRegPosIters, 36523ul);
EXPECT_EQ(sumRegVelIters, 46973ul);
EXPECT_EQ(sumToiPosIters, 44044ul);
EXPECT_EQ(sumToiVelIters, 114344ul);
//EXPECT_EQ(numSteps, 1801ul);
//EXPECT_EQ(sumRegPosIters, 36523ul);
//EXPECT_EQ(sumRegVelIters, 46973ul);
//EXPECT_EQ(sumToiPosIters, 44044ul);
//EXPECT_EQ(sumToiVelIters, 114344ul);

// From commit 04f9188c47961cafe76c55eb6b766a608593ee08 onward.
//EXPECT_EQ(numSteps, 1856ul);
Expand Down Expand Up @@ -2067,12 +2074,19 @@ TEST(World, TilesComesToRest)
{
case 4:
{
// From commit 6b16f3722d5daac80ebaefd1dfda424939498dd4 onward:
// From commit ee74290c17422ccbd6a73f07d6fd9abe960da84a onward:
EXPECT_EQ(numSteps, 1803ul);
EXPECT_EQ(sumRegPosIters, 36528ul);
EXPECT_EQ(sumRegVelIters, 46988ul);
EXPECT_EQ(sumToiPosIters, 44178ul);
EXPECT_EQ(sumToiVelIters, 114936ul);
EXPECT_EQ(sumRegPosIters, 36673ul);
EXPECT_EQ(sumRegVelIters, 48148ul);
EXPECT_EQ(sumToiPosIters, 43959ul);
EXPECT_EQ(sumToiVelIters, 113189ul);

// From commit 6b16f3722d5daac80ebaefd1dfda424939498dd4 onward:
//EXPECT_EQ(numSteps, 1803ul);
//EXPECT_EQ(sumRegPosIters, 36528ul);
//EXPECT_EQ(sumRegVelIters, 46988ul);
//EXPECT_EQ(sumToiPosIters, 44178ul);
//EXPECT_EQ(sumToiVelIters, 114936ul);

// From commit 04f9188c47961cafe76c55eb6b766a608593ee08 onward.
//EXPECT_EQ(numSteps, 1855ul);
Expand Down

0 comments on commit 0599bd9

Please sign in to comment.