Edit

kc3-lang/angle/src/tests/perf_tests/IndexConversionPerf.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2018-10-30 15:14:52
    Hash : 3402d523
    Message : Try to reduce variance in angle_perftests. This change does a few things: - make perf test runner script print % variation instead of stddev This makes it a bit more clear how much variance there is. - stabilize CPU in the render perf tests Setting a thread affinity and priority should stop from switching cores during the run. Hopefully can prevent background noise from changing the test results. - warm up the benchmark with a few iterations This should hopefully make the test results a bit more stable. - output a new normalized perf result value The new result is normalized against the number of iterations. So it should hopefully be stable even if the number of iterations is changed. - increases the iteration count in the draw call perf tests. These tests were completely dominated by SwapBuffers time. Increasing the iterations per step means we actually are bottlenecked on CPU time instead. Bug: angleproject:2923 Change-Id: I5ee347cf93df239ac33b83dc5effe4c21e066736 Reviewed-on: https://chromium-review.googlesource.com/c/1303679 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@chromium.org>

  • src/tests/perf_tests/IndexConversionPerf.cpp
  • //
    // Copyright 2015 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // IndexConversionPerf:
    //   Performance tests for ANGLE index conversion in D3D11.
    //
    
    #include <sstream>
    
    #include "ANGLEPerfTest.h"
    #include "tests/test_utils/draw_call_perf_utils.h"
    
    using namespace angle;
    
    namespace
    {
    struct IndexConversionPerfParams final : public RenderTestParams
    {
        std::string suffix() const override
        {
            std::stringstream strstr;
    
            if (indexRangeOffset > 0)
            {
                strstr << "_index_range";
            }
    
            strstr << RenderTestParams::suffix();
    
            return strstr.str();
        }
    
        unsigned int numIndexTris;
    
        // A second test, which covers using index ranges with an offset.
        unsigned int indexRangeOffset;
    };
    
    // Provide a custom gtest parameter name function for IndexConversionPerfParams.
    std::ostream &operator<<(std::ostream &stream, const IndexConversionPerfParams &param)
    {
        stream << param.suffix().substr(1);
        return stream;
    }
    
    class IndexConversionPerfTest : public ANGLERenderTest,
                                    public ::testing::WithParamInterface<IndexConversionPerfParams>
    {
      public:
        IndexConversionPerfTest();
    
        void initializeBenchmark() override;
        void destroyBenchmark() override;
        void drawBenchmark() override;
    
      private:
        void updateBufferData();
        void drawConversion();
        void drawIndexRange();
    
        GLuint mProgram;
        GLuint mVertexBuffer;
        GLuint mIndexBuffer;
        std::vector<GLushort> mIndexData;
    };
    
    IndexConversionPerfTest::IndexConversionPerfTest()
        : ANGLERenderTest("IndexConversionPerfTest", GetParam()),
          mProgram(0),
          mVertexBuffer(0),
          mIndexBuffer(0)
    {
        mRunTimeSeconds = 3.0;
    }
    
    void IndexConversionPerfTest::initializeBenchmark()
    {
        const auto &params = GetParam();
    
        ASSERT_LT(0u, params.iterationsPerStep);
        ASSERT_LT(0u, params.numIndexTris);
    
        mProgram = SetupSimpleScaleAndOffsetProgram();
        ASSERT_NE(0u, mProgram);
    
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
        // Initialize the vertex data
        size_t numTris = std::numeric_limits<GLushort>::max() / 3 + 1;
        mVertexBuffer  = Create2DTriangleBuffer(numTris, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
    
        // Initialize the index buffer
        for (unsigned int triIndex = 0; triIndex < params.numIndexTris; ++triIndex)
        {
            // Handle two different types of tests, one with index conversion triggered by a -1 index.
            if (params.indexRangeOffset == 0)
            {
                mIndexData.push_back(std::numeric_limits<GLushort>::max());
            }
            else
            {
                mIndexData.push_back(0);
            }
    
            mIndexData.push_back(1);
            mIndexData.push_back(2);
        }
    
        glGenBuffers(1, &mIndexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        updateBufferData();
    
        // Set the viewport
        glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
    
        ASSERT_GL_NO_ERROR();
    }
    
    void IndexConversionPerfTest::updateBufferData()
    {
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexData.size() * sizeof(mIndexData[0]), &mIndexData[0],
                     GL_STATIC_DRAW);
    }
    
    void IndexConversionPerfTest::destroyBenchmark()
    {
        glDeleteProgram(mProgram);
        glDeleteBuffers(1, &mVertexBuffer);
        glDeleteBuffers(1, &mIndexBuffer);
    }
    
    void IndexConversionPerfTest::drawBenchmark()
    {
        const auto &params = GetParam();
    
        if (params.indexRangeOffset == 0)
        {
            drawConversion();
        }
        else
        {
            drawIndexRange();
        }
    }
    
    void IndexConversionPerfTest::drawConversion()
    {
        const auto &params = GetParam();
    
        // Trigger an update to ensure we convert once a frame
        updateBufferData();
    
        for (unsigned int it = 0; it < params.iterationsPerStep; it++)
        {
            glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(params.numIndexTris * 3 - 1),
                           GL_UNSIGNED_SHORT, reinterpret_cast<void *>(0));
        }
    
        ASSERT_GL_NO_ERROR();
    }
    
    void IndexConversionPerfTest::drawIndexRange()
    {
        const auto &params = GetParam();
    
        unsigned int indexCount = 3;
        size_t offset           = static_cast<size_t>(indexCount * getNumStepsPerformed());
    
        offset %= (params.numIndexTris * 3);
    
        // This test increments an offset each step. Drawing repeatedly may cause the system memory
        // to release. Then, using a fresh offset will require index range validation, which pages
        // it back in. The performance should be good even if the data is was used quite a bit.
        for (unsigned int it = 0; it < params.iterationsPerStep; it++)
        {
            glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indexCount), GL_UNSIGNED_SHORT,
                           reinterpret_cast<void *>(offset));
        }
    
        ASSERT_GL_NO_ERROR();
    }
    
    IndexConversionPerfParams IndexConversionPerfD3D11Params()
    {
        IndexConversionPerfParams params;
        params.eglParameters    = egl_platform::D3D11_NULL();
        params.majorVersion     = 2;
        params.minorVersion     = 0;
        params.windowWidth      = 256;
        params.windowHeight     = 256;
        params.iterationsPerStep = 225;
        params.numIndexTris     = 3000;
        params.indexRangeOffset = 0;
        return params;
    }
    
    IndexConversionPerfParams IndexRangeOffsetPerfD3D11Params()
    {
        IndexConversionPerfParams params;
        params.eglParameters    = egl_platform::D3D11_NULL();
        params.majorVersion     = 2;
        params.minorVersion     = 0;
        params.windowWidth      = 256;
        params.windowHeight     = 256;
        params.iterationsPerStep = 16;
        params.numIndexTris     = 50000;
        params.indexRangeOffset = 64;
        return params;
    }
    
    TEST_P(IndexConversionPerfTest, Run)
    {
        run();
    }
    
    ANGLE_INSTANTIATE_TEST(IndexConversionPerfTest,
                           IndexConversionPerfD3D11Params(),
                           IndexRangeOffsetPerfD3D11Params());
    }  // namespace