From d1838338ad0e7c67e7cae514a5f58a821993f3c7 Mon Sep 17 00:00:00 2001 From: Florian De Rop <55103921+fderop@users.noreply.github.com> Date: Fri, 2 Oct 2026 03:07:23 -0700 Subject: [PATCH] Cache horizontal flips for shared rotating sprites --- Source/Entities/MOSRotating.cpp | 11 +- Source/System/ContentFile.cpp | 33 +- Source/System/ContentFile.h | 5 + Tools/Benchmarks/CaptureSpriteGame.py | 64 + Tools/Benchmarks/FlippedSprites.cpp | 222 +++ Tools/Benchmarks/FlippedSprites.md | 105 ++ Tools/Benchmarks/FlippedSprites.py | 49 + .../FlippedSpritesResults/baseline-gpu.txt | 9 + .../FlippedSpritesResults/changed-gpu.txt | 9 + .../Benchmarks/FlippedSpritesResults/draw.csv | 217 +++ .../FlippedSpritesResults/game-summary.json | 55 + .../Benchmarks/FlippedSpritesResults/game.csv | 1441 +++++++++++++++++ .../FlippedSpritesResults/summary.json | 212 +++ .../PerformanceStress.rte/Activities.ini | 10 + .../PerformanceStress.rte/Index.ini | 3 + .../PerformanceStress.rte/Stress.lua | 35 + 16 files changed, 2477 insertions(+), 3 deletions(-) create mode 100644 Tools/Benchmarks/CaptureSpriteGame.py create mode 100644 Tools/Benchmarks/FlippedSprites.cpp create mode 100644 Tools/Benchmarks/FlippedSprites.md create mode 100644 Tools/Benchmarks/FlippedSprites.py create mode 100644 Tools/Benchmarks/FlippedSpritesResults/baseline-gpu.txt create mode 100644 Tools/Benchmarks/FlippedSpritesResults/changed-gpu.txt create mode 100644 Tools/Benchmarks/FlippedSpritesResults/draw.csv create mode 100644 Tools/Benchmarks/FlippedSpritesResults/game-summary.json create mode 100644 Tools/Benchmarks/FlippedSpritesResults/game.csv create mode 100644 Tools/Benchmarks/FlippedSpritesResults/summary.json create mode 100644 Tools/Benchmarks/PerformanceStress.rte/Activities.ini create mode 100644 Tools/Benchmarks/PerformanceStress.rte/Index.ini create mode 100644 Tools/Benchmarks/PerformanceStress.rte/Stress.lua diff --git a/Source/Entities/MOSRotating.cpp b/Source/Entities/MOSRotating.cpp index fd036c301f..0b357c7f1c 100644 --- a/Source/Entities/MOSRotating.cpp +++ b/Source/Entities/MOSRotating.cpp @@ -1696,13 +1696,20 @@ void MOSRotating::Draw(BITMAP* pTargetBitmap, const Vector& targetPos, DrawMode } if (m_HFlipped && pFlipBitmap) { - bool drawIntermediate = mode != g_DrawMOID; + bool cachedColor = false; + if (mode == g_DrawColor && !m_SpriteModified && pFlipBitmap->w == m_aSprite[m_Frame]->w && pFlipBitmap->h == m_aSprite[m_Frame]->h) { + if (BITMAP* cachedBitmap = ContentFile::GetFlippedBitmap(m_aSprite[m_Frame])) { + pFlipBitmap = cachedBitmap; + cachedColor = true; + } + } + bool drawIntermediate = !cachedColor && mode != g_DrawMOID && mode != g_DrawTrans; if (drawIntermediate) { // Don't size the intermediate bitmaps to the m_Scale, because the scaling happens after they are done clear_to_color(pFlipBitmap, keyColor); // Draw either the source color bitmap or the intermediate material bitmap onto the intermediate flipping bitmap - if (mode == g_DrawColor || mode == g_DrawTrans) { + if (mode == g_DrawColor) { draw_sprite_h_flip(pFlipBitmap, m_aSprite[m_Frame], 0, 0); } else { // If using the temp bitmap (which is always larger than the sprite) make sure the flipped image ends up in the upper right corner as if it was just as small as the sprite bitmap diff --git a/Source/System/ContentFile.cpp b/Source/System/ContentFile.cpp index 3d7b9b4b8f..46ba2ffd0c 100644 --- a/Source/System/ContentFile.cpp +++ b/Source/System/ContentFile.cpp @@ -20,6 +20,7 @@ using namespace RTE; const std::string ContentFile::c_ClassName = "ContentFile"; std::array, ContentFile::BitDepths::BitDepthCount> ContentFile::s_LoadedBitmaps; +std::unordered_map ContentFile::s_FlippedBitmaps; std::unordered_map ContentFile::s_MemoryPNGs; std::unordered_map ContentFile::s_LoadedSamples; std::unordered_map ContentFile::s_PathHashes; @@ -53,6 +54,10 @@ int ContentFile::Create(const ContentFile& reference) { } void ContentFile::FreeAllLoaded() { + for (const auto& [source, flipped]: s_FlippedBitmaps) { + destroy_bitmap(flipped); + } + s_FlippedBitmaps.clear(); for (int depth = BitDepths::Eight; depth < BitDepths::BitDepthCount; ++depth) { for (const auto& [bitmapPath, bitmapPtr]: s_LoadedBitmaps[depth]) { destroy_bitmap(bitmapPtr); @@ -210,7 +215,8 @@ void ContentFile::ManuallyLoadDataPNG(const std::string& filePath, SDL_Surface* surface->w * SDL_BYTESPERPIXEL(surface->format)); } - s_LoadedBitmaps[BitDepths::Eight].try_emplace(filePath, bitmap); + auto [entry, inserted] = s_LoadedBitmaps[BitDepths::Eight].try_emplace(filePath, bitmap); + s_FlippedBitmaps.try_emplace(entry->second, nullptr); } void ContentFile::ReloadAllBitmaps() { @@ -222,6 +228,27 @@ void ContentFile::ReloadAllBitmaps() { g_ConsoleMan.PrintString("SYSTEM: Sprites reloaded"); } +BITMAP* ContentFile::GetFlippedBitmap(BITMAP* bitmap) { + auto entry = s_FlippedBitmaps.find(bitmap); + if (entry == s_FlippedBitmaps.end()) { + return nullptr; + } + if (!entry->second) { + entry->second = create_bitmap_ex(8, bitmap->w, bitmap->h); + clear_to_color(entry->second, ColorKeys::g_MaskColor); + draw_sprite_h_flip(entry->second, bitmap, 0, 0); + } + return entry->second; +} + +void ContentFile::RemoveFlippedBitmap(BITMAP* bitmap) { + auto entry = s_FlippedBitmaps.find(bitmap); + if (entry != s_FlippedBitmaps.end()) { + destroy_bitmap(entry->second); + s_FlippedBitmaps.erase(entry); + } +} + BITMAP* ContentFile::GetAsBitmap(int conversionMode, bool storeBitmap, const std::string& dataPathToSpecificFrame) { if (m_DataPath.empty()) { return nullptr; @@ -243,6 +270,7 @@ BITMAP* ContentFile::GetAsBitmap(int conversionMode, bool storeBitmap, const std std::unordered_map::iterator foundBitmap = s_LoadedBitmaps[BitDepths::Eight].find(dataPathToLoad); if (foundBitmap != s_LoadedBitmaps[BitDepths::Eight].end()) { returnBitmap = foundBitmap->second; + RemoveFlippedBitmap(returnBitmap); s_LoadedBitmaps[BitDepths::Eight].erase(dataPathToLoad); } @@ -269,6 +297,7 @@ BITMAP* ContentFile::GetAsBitmap(int conversionMode, bool storeBitmap, const std // Insert the bitmap into the map, PASSING OVER OWNERSHIP OF THE LOADED DATAFILE if (storeBitmap) { s_LoadedBitmaps[bitDepth].try_emplace(dataPathToLoad, returnBitmap); + s_FlippedBitmaps.try_emplace(returnBitmap, nullptr); } } @@ -448,6 +477,8 @@ void ContentFile::ReloadBitmap(const std::string& filePath, int conversionMode) set_color_conversion((conversionMode == COLORCONV_NONE) ? COLORCONV_NONE : conversionMode); BITMAP* loadedBitmap = (*bmpItr).second; + RemoveFlippedBitmap(loadedBitmap); + s_FlippedBitmaps.try_emplace(loadedBitmap, nullptr); SDL_Surface* newImage = LoadImageAsSurface(conversionMode, filePath); diff --git a/Source/System/ContentFile.h b/Source/System/ContentFile.h index 454511d13b..94129699c5 100644 --- a/Source/System/ContentFile.h +++ b/Source/System/ContentFile.h @@ -124,6 +124,9 @@ namespace RTE { /// Reloads all BITMAPs in the cache from disk, allowing any changes to be reflected at runtime. static void ReloadAllBitmaps(); + /// Gets a cached horizontal flip of a loaded sprite bitmap, or nullptr for a bitmap outside this cache. Ownership stays with ContentFile. + static BITMAP* GetFlippedBitmap(BITMAP* bitmap); + /// Gets the data represented by this ContentFile object as an Allegro BITMAP, loading it into the static maps if it's not already loaded. Note that ownership of the BITMAP is NOT transferred! /// @param conversionMode The Allegro color conversion mode to use when loading this bitmap. /// @param storeBitmap Whether to store the BITMAP in the relevant static map after loading it or not. If this is false, ownership of the BITMAP IS transferred! @@ -180,6 +183,7 @@ namespace RTE { static std::unordered_map s_PathHashes; //!< Static map containing the hash values of paths of all loaded data files. static std::array, BitDepths::BitDepthCount> s_LoadedBitmaps; //!< Static map containing all the already loaded BITMAPs and their paths for each bit depth. + static std::unordered_map s_FlippedBitmaps; //!< Horizontal flips of unmodified shared sprite bitmaps. static std::unordered_map s_MemoryPNGs; //!< Static map containing in-memory PNG files for save/load static std::unordered_map s_LoadedSamples; //!< Static map containing all the already loaded FSOUND_SAMPLEs and their paths. @@ -239,6 +243,7 @@ namespace RTE { /// @param filePath The filepath to the bitmap we want to reload. /// @param conversionMode The Allegro color conversion mode to use when reloading this bitmap. static void ReloadBitmap(const std::string& filePath, int conversionMode = 0); + static void RemoveFlippedBitmap(BITMAP* bitmap); /// Set alpha value of non mask color pixels to 255 for 32-bit bitmaps. (WARN: would override existing alpha values!) static void AddAlphaChannel(BITMAP* bitmap); diff --git a/Tools/Benchmarks/CaptureSpriteGame.py b/Tools/Benchmarks/CaptureSpriteGame.py new file mode 100644 index 0000000000..0cd0267c14 --- /dev/null +++ b/Tools/Benchmarks/CaptureSpriteGame.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +import argparse +import json +import pathlib +import shlex +import subprocess + +parser = argparse.ArgumentParser(description='Build seeded game captures from the FlippedSprites engine objects.') +parser.add_argument('build_directory', type=pathlib.Path) +parser.add_argument('output_directory', type=pathlib.Path) +parser.add_argument('--replace-object', action='append', default=[]) +args = parser.parse_args() +build = args.build_directory.resolve() +output = args.output_directory.resolve() +repo = pathlib.Path(__file__).resolve().parents[2] +commands = json.loads((build / 'compile_commands.json').read_text()) +movable = (repo / 'Source/Managers/MovableMan.cpp').read_text() +movable = 'namespace RTE { long long profileTravel=0, profileColor=0, profileClear=0; }\n' + movable +movable = movable.replace('void MovableMan::Update() {', 'void MovableMan::Update() {\n profileTravel=profileColor=profileClear=0;') +movable = movable.replace('g_SceneMan.ClearMOColorLayer();', '{ const auto started=g_TimerMan.GetAbsoluteTime(); g_SceneMan.ClearMOColorLayer(); profileClear=g_TimerMan.GetAbsoluteTime()-started; }') +movable = movable.replace('\tTravel();', '\t{ const auto started=g_TimerMan.GetAbsoluteTime(); Travel(); profileTravel=g_TimerMan.GetAbsoluteTime()-started; }') +movable = movable.replace('Draw(g_SceneMan.GetMOColorBitmap());', '{ const auto started=g_TimerMan.GetAbsoluteTime(); Draw(g_SceneMan.GetMOColorBitmap()); profileColor=g_TimerMan.GetAbsoluteTime()-started; }') +main = (repo / 'Source/Main.cpp').read_text() +main = main.replace('void RunGameLoop() {', '''namespace RTE { extern long long profileTravel, profileColor, profileClear; } +void RunGameLoop() { + struct CaptureSample { long long simulation, movable; int particles; long long travel, color, clear, gridWait; }; + std::vector captureSamples; +''') +main = main.replace('g_PerformanceMan.StartPerformanceMeasurement(PerformanceMan::SimTotal);', '''g_RandomGenerator.Seed(731 + captureSamples.size()); + const auto captureStart=g_TimerMan.GetAbsoluteTime(); + g_PerformanceMan.StartPerformanceMeasurement(PerformanceMan::SimTotal);''') +main = main.replace('g_MovableMan.CompleteQueuedMOIDDrawings();', '''const auto waitStart=g_TimerMan.GetAbsoluteTime(); + g_MovableMan.CompleteQueuedMOIDDrawings(); + const auto gridWait=g_TimerMan.GetAbsoluteTime()-waitStart;''') +main = main.replace('g_MovableMan.Update();', '''const auto movableStart=g_TimerMan.GetAbsoluteTime(); + g_MovableMan.Update(); + const auto movableEnd=g_TimerMan.GetAbsoluteTime();''') +main = main.replace('g_PerformanceMan.StopPerformanceMeasurement(PerformanceMan::SimTotal);', '''g_PerformanceMan.StopPerformanceMeasurement(PerformanceMan::SimTotal); + captureSamples.push_back({g_TimerMan.GetAbsoluteTime()-captureStart, movableEnd-movableStart, g_MovableMan.GetParticleCount(), profileTravel, profileColor, profileClear, gridWait});''') +main = main.replace('g_PerformanceMan.UpdateMSPF(updateTotalTime, drawTotalTime);', '''g_PerformanceMan.UpdateMSPF(updateTotalTime, drawTotalTime); + if (captureSamples.size() >= 240) { + for (size_t i=0; i +#include +using namespace RTE; + +struct SceneAccess : SceneMan { + static Scene* SceneMan::* currentScene() { return &SceneAccess::m_pCurrentScene; } +}; +struct TerrainFixture : SLTerrain { + TerrainFixture(const std::string& path) { + m_BitmapFile = ContentFile(path.c_str()); m_WrapX = true; m_WrapY = false; Create(); + } +}; +Material fixtureMaterial; +struct SpriteFixture : MOSRotating { + SpriteFixture(const std::vector& frames, int i) { + m_aSprite = frames; + m_FrameCount = frames.size(); + int width = frames[0]->w, height = frames[0]->h; + m_pFlipBitmap = create_bitmap_ex(8, width, height); + m_pTempBitmap = create_bitmap_ex(8, width * 2, height * 2); + m_SpriteOffset = Vector(-width * 0.5F + 0.25F, -height * 0.5F - 0.75F); + m_SpriteRadius = std::hypot(width, height); + m_SpriteDiameter = m_SpriteRadius * 2; + m_Pos = Vector(80 + i % 8 * 48, 80 + i / 8 % 8 * 48); + m_HFlipped = true; + m_Rotation.SetRadAngle(i * 0.137F); + } + ~SpriteFixture() override { destroy_bitmap(m_pTempBitmap); m_pTempBitmap = nullptr; } + Material const* GetMaterial() const override { return &fixtureMaterial; } + void configure(int frame, bool flip, float angle, float scale, Vector position) { + m_Frame = frame; m_HFlipped = flip; m_Rotation.SetRadAngle(angle); m_Scale = scale; m_Pos = position; + } + void overwriteScratch() { clear_to_color(m_pFlipBitmap, 173); } + void flash() { m_FlashWhiteTimer.Reset(); m_FlashWhiteTimer.SetRealTimeLimitMS(10000); } + void stopFlash() { m_FlashWhiteTimer.SetRealTimeLimitMS(0); } + void copySprite(const SpriteFixture& reference) { MOSprite::Create(reference); } +}; +static_assert(sizeof(SpriteFixture) == sizeof(MOSRotating)); +uint64_t hashBytes(uint64_t hash, const unsigned char* bytes, size_t size) { + for (size_t i = 0; i < size; ++i) hash = (hash ^ bytes[i]) * 1099511628211ULL; + return hash; +} +uint64_t hashBitmap(uint64_t hash, BITMAP* bitmap) { + for (int y = 0; y < bitmap->h; ++y) hash = hashBytes(hash, bitmap->line[y], bitmap->w); + return hash; +} +BITMAP* pattern(int width, int height, int seed) { + BITMAP* bitmap = create_bitmap_ex(8, width, height); + for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x) + _putpixel(bitmap, x, y, (x * 17 + y * 13 + seed) % 7 == 0 || x < y / 3 ? 0 : 20 + (x + y + seed) % 200); + return bitmap; +} +double milliseconds(std::chrono::steady_clock::time_point start) { + return std::chrono::duration(std::chrono::steady_clock::now() - start).count(); +} +int main(int argc, char** argv) { + std::cout << std::unitbuf; + install_allegro(SYSTEM_NONE, &errno, atexit); + System::EnableFilePathCaseSensitivity(false); + ThreadMan::Construct(); TimerMan::Construct(); SettingsMan::Construct(); PresetMan::Construct(); + SceneMan::Construct(); MovableMan::Construct(); LuaMan::Construct(); ConsoleMan::Construct(); FrameMan::Construct(); + fixtureMaterial.SetIndex(37); + PALETTE palette{}; + for (int i = 0; i < 256; ++i) palette[i].r = palette[i].g = palette[i].b = i % 64; + std::string fixturePath = "Mods/FlippedSpritesBenchmark-" + std::to_string(getpid()); + std::filesystem::create_directories(fixturePath); + std::vector paths; + auto loadPattern = [&](int width, int height, int seed) { + std::string path = fixturePath + "/" + std::to_string(paths.size()) + ".bmp"; + BITMAP* bitmap = pattern(width, height, seed); + save_bitmap(path.c_str(), bitmap, palette); destroy_bitmap(bitmap); + paths.push_back(path); + return ContentFile(path.c_str()).GetAsBitmap(); + }; + std::string terrainPath = fixturePath + "/terrain.bmp"; + BITMAP* terrainBitmap = pattern(512, 512, 0); + save_bitmap(terrainPath.c_str(), terrainBitmap, palette); destroy_bitmap(terrainBitmap); + Scene scene; + scene.Create(new TerrainFixture(terrainPath)); + std::filesystem::remove(terrainPath); + g_SceneMan.*SceneAccess::currentScene() = &scene; + BITMAP* target = create_bitmap_ex(8, 512, 512); + std::vector sources; + for (int seed = 0; seed < 3; ++seed) sources.push_back(loadPattern(24 + seed % 2 * 8, 20 + seed % 2 * 8, seed)); + uint64_t hash = 1469598103934665603ULL; + int cases = 0; + { + SpriteFixture sprite(sources, 0); + for (int frame = 0; frame < 3; ++frame) for (bool flip : {false, true}) + for (float angle : {0.0F, 0.13F, -1.27F, 3.14159265F}) for (float scale : {0.5F, 1.0F, 1.7F}) + for (Vector camera : {Vector(), Vector(-50, 0), Vector(300, 0)}) + for (DrawMode mode : {g_DrawColor, g_DrawWhite, g_DrawMaterial, g_DrawDoor, g_DrawColor}) { + sprite.configure(frame, flip, angle, scale, Vector(cases % 2 ? 5 : 507, 200.75F)); + sprite.overwriteScratch(); + clear_to_color(target, 11); + sprite.Draw(target, camera, mode, true); + hash = hashBitmap(hash, target); ++cases; + } + sprite.configure(0, true, 0.23F, 1, Vector(200, 200)); + for (int edit = 0; edit < 4; ++edit) { + if (edit) sprite.SetSpritePixelIndex(8 + edit, 10, 0, 43 + edit, -1, false); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + } + sprite.SetAllSpritePixelIndexes(0, 63, 0, false); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + SpriteFixture clone(sources, 0); + clone.copySprite(sprite); + for (int edit = 0; edit < 3; ++edit) { + sprite.SetSpritePixelIndex(11 + edit, 10, 0, 112 + edit, -1, false); + clear_to_color(target, 11); clone.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + } + sprite.flash(); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + sprite.stopFlash(); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + } + std::string path = fixturePath + "/reload.bmp"; + save_bitmap(path.c_str(), sources[0], palette); + BITMAP* loaded = ContentFile(path.c_str()).GetAsBitmap(); + { + SpriteFixture sprite({loaded}, 0); + for (int reload = 0; reload < 3; ++reload) { + if (reload) { + BITMAP* replacement = pattern(24 + (reload == 2 ? 8 : 0), 20, 77 + reload); + save_bitmap(path.c_str(), replacement, palette); destroy_bitmap(replacement); + ContentFile::ReloadAllBitmaps(); + if (ContentFile(path.c_str()).GetAsBitmap() != loaded) return 2; + } + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + } + } + std::filesystem::remove(path); + std::string memoryPath = fixturePath + "/memory.png"; + SDL_Surface* surface = SDL_CreateSurface(24, 20, SDL_PIXELFORMAT_INDEX8); + for (int y = 0; y < 20; ++y) std::memcpy(static_cast(surface->pixels) + y * surface->pitch, sources[0]->line[y], 24); + ContentFile::ManuallyLoadDataPNG(memoryPath, surface); + ContentFile memoryFile(memoryPath.c_str()); + BITMAP* transferred = memoryFile.GetAsBitmap(); + { + SpriteFixture sprite({transferred}, 0); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + if (memoryFile.GetAsBitmap(0, false) != transferred) return 4; + for (int edit = 0; edit < 2; ++edit) { + _putpixel(transferred, 5 + edit, 6, 78 + edit); + clear_to_color(target, 11); sprite.Draw(target, Vector(), g_DrawColor, true); + hash = hashBitmap(hash, target); ++cases; + } + } + destroy_bitmap(transferred); + std::cout << "behavior_hash=" << hash << " cases=" << cases << '\n'; + if (argc > 1 && std::string(argv[1]) == "--gpu") { + GLResourceMan::Construct(); + g_FrameMan.SetTransTableFromPreset(TransparencyPreset::HalfTrans); + SDL_Init(SDL_INIT_VIDEO); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_Window* window = SDL_CreateWindow("Draw benchmark", 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN); + SDL_GLContext context = SDL_GL_CreateContext(window); + gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress); + rlLoadExtensions((void*)SDL_GL_GetProcAddress); + rlglInit(512, 512); rlViewport(0, 0, 512, 512); + rlMatrixMode(RL_PROJECTION); rlLoadIdentity(); rlOrtho(0, 512, 512, 0, -1, 1); + rlMatrixMode(RL_MODELVIEW); rlLoadIdentity(); + uint64_t gpuHash = 1469598103934665603ULL; + SpriteFixture sprite({sources[0]}, 0); + for (bool flip : {false, true}) for (float angle : {0.0F, 0.17F, -0.95F}) { + sprite.configure(0, flip, angle, 1, Vector(200, 200)); + glClearColor(0.17F, 0.23F, 0.31F, 1); glClear(GL_COLOR_BUFFER_BIT); + sprite.Draw(target, Vector(), g_DrawTrans, true); + rlDrawRenderBatchActive(); + std::vector pixels(512 * 512 * 4); + glReadPixels(0, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data()); + int drawnPixels = 0; + for (size_t i = 0; i < pixels.size(); i += 4) drawnPixels += std::memcmp(pixels.data(), pixels.data() + i, 4) != 0; + if (!drawnPixels) return 3; + std::cout << "gpu_flip=" << flip << " angle=" << angle << " drawn_pixels=" << drawnPixels << '\n'; + gpuHash = hashBytes(gpuHash, pixels.data(), pixels.size()); + } + std::cout << "gpu_hash=" << gpuHash << " cases=6\n"; + g_GLResourceMan.Destroy(); rlglClose(); SDL_GL_DestroyContext(context); SDL_DestroyWindow(window); SDL_Quit(); + } else if (argc == 1) { + for (auto [size, unique] : {std::pair{12, 1}, {24, 8}, {64, 8}, {128, 8}, {24, 512}, {64, 512}}) { + std::vector frames; + for (int i = 0; i < unique; ++i) frames.push_back(loadPattern(size, size, i)); + std::vector> objects; + for (int i = 0; i < 512; ++i) objects.push_back(std::make_unique(std::vector{frames[i % unique]}, i)); + auto start = std::chrono::steady_clock::now(); + for (const auto& object : objects) object->Draw(target, Vector(), g_DrawColor, true); + std::cout << "size=" << size << " unique=" << unique << " cold_ms=" << milliseconds(start) << " draws=512\n"; + for (int sample = -1; sample < 5; ++sample) { + start = std::chrono::steady_clock::now(); + for (int repeat = 0; repeat < 128; ++repeat) for (const auto& object : objects) object->Draw(target, Vector(), g_DrawColor, true); + if (sample >= 0) std::cout << "size=" << size << " unique=" << unique << " sample=" << sample << " ms=" << milliseconds(start) << " draws=65536\n"; + } + std::cout << "size=" << size << " unique=" << unique << " pixels_hash=" << hashBitmap(1469598103934665603ULL, target) << '\n'; + } + } + ContentFile::FreeAllLoaded(); + std::filesystem::remove_all(fixturePath); + destroy_bitmap(target); + g_SceneMan.*SceneAccess::currentScene() = nullptr; +} diff --git a/Tools/Benchmarks/FlippedSprites.md b/Tools/Benchmarks/FlippedSprites.md new file mode 100644 index 0000000000..9fb2f79710 --- /dev/null +++ b/Tools/Benchmarks/FlippedSprites.md @@ -0,0 +1,105 @@ +The sprite benchmark calls the production `MOSRotating::Draw` function through 512 debris fixtures. +It links the existing release engine objects, with separate baseline and changed `MOSRotating` and `ContentFile` objects. +The fixtures load patterned BMPs through `ContentFile`. +Each sample contains 65,536 flipped color draws, with rotation and scene wrapping. +Each process includes one warmup sample and five recorded samples per workload. + +The pixel checks cover 1,096 cases. +These cases include frame changes, flips, rotations, scales, scene seams, camera offsets, white flashes, material silhouettes, and door silhouettes. +They also cover scratch bitmap changes, repeated sprite edits, copies of edited sprites, reloads, changed source dimensions, and memory bitmap ownership transfer. +The GPU checks call the production transparent draw path in a real OpenGL context. +They read six framebuffer images and require visible pixels. + +Baseline and changed builds produced the same CPU hash: `15073311523546579531`. +Both builds produced the same GPU hash: `15926731766284440575`. +All six workload pixel hashes also matched across all processes. +The GPU startup prints one `GLAD: ERROR 1280 in glGetIntegerv!` message in both builds. +The six draws produce visible pixels and matching framebuffer hashes. + +The measurements used an Apple M3 Pro with GCC 15.2.0, C++20, `-O3`, and `NDEBUG`. +The baseline revision was `41e6b7010817936e09d2929330b7519852a1fcca`. +Three process pairs ran in this order: baseline/changed, changed/baseline, baseline/changed. +The table uses the median of 15 samples per workload. + +| Sprite size | Unique assets | Baseline, ms | Changed, ms | CPU time reduction | Added bitmap storage | +| --- | ---: | ---: | ---: | ---: | ---: | +| 12×12 | 1 | 22.355 | 15.843 | 29.1% | 344 B | +| 24×24 | 8 | 90.951 | 61.750 | 32.1% | 6.8 KiB | +| 64×64 | 8 | 484.790 | 331.360 | 31.6% | 36.8 KiB | +| 128×128 | 8 | 1593.830 | 1028.640 | 35.5% | 136.8 KiB | +| 24×24 | 512 | 88.733 | 66.646 | 24.9% | 436 KiB | +| 64×64 | 512 | 491.085 | 346.401 | 29.5% | 2.30 MiB | + +The added bitmap storage includes pixel data, row pointers, and the 104-byte `BITMAP` header on this machine. +It excludes allocator overhead and the map nodes and buckets. +The map keeps one entry per loaded bitmap, with a null value until the first cached flip. +The cache retains flipped bitmaps until reload, ownership transfer, or content cleanup. + +Cold measurements cover the first 512 draws after the source files load. +With 512 unique assets, the 24×24 workload increased from 0.839 ms to 0.889 ms. +The 64×64 workload increased from 4.054 ms to 4.241 ms. +These costs include the first flip allocations. +The workloads with shared assets also improved on their first draw pass. + +The full game ran three alternating pairs with 400 collidable stock gibs and a frag grenade explosion every 60 ticks. +The included activity uses Grasslands and the stock `Gib Metal Grey Small A` preset. +The capture seeds the random generator with `731 + tick` and stops after 240 simulation ticks. +The comparison excludes the first 60 ticks. +All six captures had identical particle counts at every tick, with a peak of 883 particles. + +| Full game measurement | Baseline | Changed | +| --- | ---: | ---: | +| Median of color draw means | 129.394 µs | 102.106 µs | +| Median of simulation means | 2534.261 µs | 2497.439 µs | +| Median of simulation 95th percentiles | 8072 µs | 8177 µs | + +Color drawing took 21.1% less CPU time. +The total simulation difference was about 1.5%, with variation between runs. +Travel still took about 2 ms per simulation tick. +These measurements support a rendering improvement, with limited evidence of a total simulation improvement. +Whole frame measurements had a timer outlier and do not support a frame rate claim. + +Raw draw samples are in [draw.csv](FlippedSpritesResults/draw.csv). +Raw game samples are in [game.csv](FlippedSpritesResults/game.csv). +The results directory also contains the workload summaries and the GPU outputs. + +Build the engine with Meson and Ninja before you compile the benchmark. +Run this command from the repository root: + +```sh +python3 Tools/Benchmarks/FlippedSprites.py build /tmp/flipped-sprites +``` + +The runner builds the baseline sources from Git and the changed sources from the current working tree. +If the reused engine build contains other changes, pass `--replace-object Name=/absolute/path/to/pristine/object.o` for each affected object. +The recorded comparison used pristine `Matrix` and `MOSprite` objects. +The runner adds only static members to `ContentFile`; engine object layouts stay compatible. + +On macOS, run the pixel checks and GPU checks with the engine library directory: + +```sh +DYLD_LIBRARY_PATH="$PWD/external/lib/macos" /tmp/flipped-sprites/baseline --check +DYLD_LIBRARY_PATH="$PWD/external/lib/macos" /tmp/flipped-sprites/changed --check +DYLD_LIBRARY_PATH="$PWD/external/lib/macos" /tmp/flipped-sprites/baseline --gpu +DYLD_LIBRARY_PATH="$PWD/external/lib/macos" /tmp/flipped-sprites/changed --gpu +``` + +For CPU measurements, omit the final argument. +Repeat each executable three times and alternate the process order. +On Linux, use `LD_LIBRARY_PATH` with the engine library directory. +The fixtures disable the engine file path cache because they create new BMP files after startup. +The fixture size assertion protects the fixed object pool allocation used by `MOSRotating`. + +For a full game capture, run this command with the same object replacement arguments: + +```sh +python3 Tools/Benchmarks/CaptureSpriteGame.py build /tmp/flipped-sprites +``` + +Copy [PerformanceStress.rte](PerformanceStress.rte) into the runtime `Mods` directory. +In `Userdata/Settings.ini`, set `LaunchIntoActivity = 1`, `DefaultActivityType = GAScripted`, and `DefaultActivityName = Debris Performance Stress`. +Set `DefaultSceneName = Grasslands`. +Run each capture executable from the normal game runtime directory, with the normal libraries and data. +On macOS, copy the executable into the existing app bundle before you run it. +Capture the `-cout` output until `PERF_CAPTURE_DONE`, then stop the process. +Repeat three pairs and compare the `PERF_PROFILE` rows from ticks 60 through 239. diff --git a/Tools/Benchmarks/FlippedSprites.py b/Tools/Benchmarks/FlippedSprites.py new file mode 100644 index 0000000000..c9fd2ae1b3 --- /dev/null +++ b/Tools/Benchmarks/FlippedSprites.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +import argparse +import json +import pathlib +import shlex +import subprocess + +parser = argparse.ArgumentParser(description='Link baseline and changed Draw benchmarks with real engine objects.') +parser.add_argument('build_directory', type=pathlib.Path) +parser.add_argument('output_directory', type=pathlib.Path) +parser.add_argument('--baseline-ref', default='41e6b7010817936e09d2929330b7519852a1fcca') +parser.add_argument('--replace-object', action='append', default=[], help='Name=/path/to/pristine/object.o') +args = parser.parse_args() +build = args.build_directory.resolve() +output = args.output_directory.resolve() +output.mkdir(parents=True, exist_ok=True) +repo = pathlib.Path(__file__).resolve().parents[2] +commands = json.loads((build / 'compile_commands.json').read_text()) + +def compile_file(name, source, destination): + command = shlex.split(next(x['command'] for x in commands if x['file'].endswith('/' + name))) + command = command[:command.index('-MD')] + command = [arg for arg in command if arg not in {'-ICortexCommand.p', '-fpch-preprocess'}] + includes = ['-I' + str(path) for path in [repo / 'Source', *(repo / 'Source').iterdir()] if path.is_dir()] + command[1:1] = includes + command += ['-g', '-c', str(source), '-o', str(destination)] + subprocess.run(command, cwd=build, check=True) + +benchmark = output / 'benchmark.o' +compile_file('MOSRotating.cpp', pathlib.Path(__file__).with_suffix('.cpp'), benchmark) +base_link = shlex.split(subprocess.check_output(['ninja', '-C', str(build), '-t', 'commands', 'CortexCommand'], text=True).splitlines()[-1]) +for variant in ['baseline', 'changed']: + replacements = dict(argument.split('=', 1) for argument in args.replace_object) + for name, folder in [('MOSRotating', 'Entities'), ('ContentFile', 'System')]: + relative = 'Source/' + folder + '/' + name + '.cpp' + source = repo / relative + if variant == 'baseline': + source = output / (name + '-baseline.cpp') + source.write_bytes(subprocess.check_output(['git', 'show', args.baseline_ref + ':' + relative], cwd=repo)) + destination = output / (name + '-' + variant + '.o') + compile_file(name + '.cpp', source, destination) + replacements[name] = str(destination) + link = base_link.copy() + link[link.index('-o') + 1] = str(output / variant) + link[link.index('CortexCommand.p/Source_Main.cpp.o')] = str(benchmark) + for name, path in replacements.items(): + index = next(i for i, arg in enumerate(link) if arg.endswith('_' + name + '.cpp.o')) + link[index] = str(pathlib.Path(path).resolve()) + subprocess.run(link, cwd=build, check=True) diff --git a/Tools/Benchmarks/FlippedSpritesResults/baseline-gpu.txt b/Tools/Benchmarks/FlippedSpritesResults/baseline-gpu.txt new file mode 100644 index 0000000000..a023d5ed2a --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/baseline-gpu.txt @@ -0,0 +1,9 @@ +behavior_hash=15073311523546579531 cases=1096 +GLAD: ERROR 1280 in glGetIntegerv! +gpu_flip=0 angle=0 drawn_pixels=480 +gpu_flip=0 angle=0.17 drawn_pixels=479 +gpu_flip=0 angle=-0.95 drawn_pixels=482 +gpu_flip=1 angle=0 drawn_pixels=480 +gpu_flip=1 angle=0.17 drawn_pixels=480 +gpu_flip=1 angle=-0.95 drawn_pixels=481 +gpu_hash=15926731766284440575 cases=6 diff --git a/Tools/Benchmarks/FlippedSpritesResults/changed-gpu.txt b/Tools/Benchmarks/FlippedSpritesResults/changed-gpu.txt new file mode 100644 index 0000000000..a023d5ed2a --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/changed-gpu.txt @@ -0,0 +1,9 @@ +behavior_hash=15073311523546579531 cases=1096 +GLAD: ERROR 1280 in glGetIntegerv! +gpu_flip=0 angle=0 drawn_pixels=480 +gpu_flip=0 angle=0.17 drawn_pixels=479 +gpu_flip=0 angle=-0.95 drawn_pixels=482 +gpu_flip=1 angle=0 drawn_pixels=480 +gpu_flip=1 angle=0.17 drawn_pixels=480 +gpu_flip=1 angle=-0.95 drawn_pixels=481 +gpu_hash=15926731766284440575 cases=6 diff --git a/Tools/Benchmarks/FlippedSpritesResults/draw.csv b/Tools/Benchmarks/FlippedSpritesResults/draw.csv new file mode 100644 index 0000000000..5367510b1e --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/draw.csv @@ -0,0 +1,217 @@ +variant,pair,size,unique,sample,ms +baseline,1,12,1,cold,0.278 +baseline,1,12,1,0,22.739 +baseline,1,12,1,1,22.475 +baseline,1,12,1,2,22.467 +baseline,1,12,1,3,22.355 +baseline,1,12,1,4,22.396 +baseline,1,24,8,cold,0.822 +baseline,1,24,8,0,91.683 +baseline,1,24,8,1,90.741 +baseline,1,24,8,2,90.863 +baseline,1,24,8,3,90.657 +baseline,1,24,8,4,90.265 +baseline,1,64,8,cold,3.964 +baseline,1,64,8,0,487.292 +baseline,1,64,8,1,485.389 +baseline,1,64,8,2,482.23 +baseline,1,64,8,3,482.086 +baseline,1,64,8,4,481.937 +baseline,1,128,8,cold,12.586 +baseline,1,128,8,0,1588.73 +baseline,1,128,8,1,1591.02 +baseline,1,128,8,2,1588.78 +baseline,1,128,8,3,1594.71 +baseline,1,128,8,4,1586.96 +baseline,1,24,512,cold,0.825 +baseline,1,24,512,0,88.658 +baseline,1,24,512,1,88.661 +baseline,1,24,512,2,88.546 +baseline,1,24,512,3,88.853 +baseline,1,24,512,4,88.576 +baseline,1,64,512,cold,3.949 +baseline,1,64,512,0,482.625 +baseline,1,64,512,1,481.428 +baseline,1,64,512,2,482.648 +baseline,1,64,512,3,482.758 +baseline,1,64,512,4,484.009 +baseline,2,12,1,cold,0.271 +baseline,2,12,1,0,22.36 +baseline,2,12,1,1,22.413 +baseline,2,12,1,2,22.258 +baseline,2,12,1,3,22.244 +baseline,2,12,1,4,22.226 +baseline,2,24,8,cold,0.858 +baseline,2,24,8,0,90.807 +baseline,2,24,8,1,90.951 +baseline,2,24,8,2,92.055 +baseline,2,24,8,3,90.858 +baseline,2,24,8,4,90.484 +baseline,2,64,8,cold,3.979 +baseline,2,64,8,0,484.073 +baseline,2,64,8,1,483.957 +baseline,2,64,8,2,484.778 +baseline,2,64,8,3,484.79 +baseline,2,64,8,4,484.361 +baseline,2,128,8,cold,12.416 +baseline,2,128,8,0,1596.3 +baseline,2,128,8,1,1593.83 +baseline,2,128,8,2,1591.36 +baseline,2,128,8,3,1601.8 +baseline,2,128,8,4,1611.45 +baseline,2,24,512,cold,0.839 +baseline,2,24,512,0,93.83 +baseline,2,24,512,1,93.802 +baseline,2,24,512,2,93.817 +baseline,2,24,512,3,93.841 +baseline,2,24,512,4,93.71 +baseline,2,64,512,cold,4.072 +baseline,2,64,512,0,498.586 +baseline,2,64,512,1,495.821 +baseline,2,64,512,2,496.68 +baseline,2,64,512,3,496.972 +baseline,2,64,512,4,497.039 +baseline,3,12,1,cold,0.272 +baseline,3,12,1,0,22.429 +baseline,3,12,1,1,22.215 +baseline,3,12,1,2,22.141 +baseline,3,12,1,3,22.178 +baseline,3,12,1,4,22.149 +baseline,3,24,8,cold,0.874 +baseline,3,24,8,0,92.551 +baseline,3,24,8,1,95.023 +baseline,3,24,8,2,94.463 +baseline,3,24,8,3,100.234 +baseline,3,24,8,4,98.671 +baseline,3,64,8,cold,4.288 +baseline,3,64,8,0,499.412 +baseline,3,64,8,1,498.833 +baseline,3,64,8,2,497.802 +baseline,3,64,8,3,498.792 +baseline,3,64,8,4,498.807 +baseline,3,128,8,cold,12.634 +baseline,3,128,8,0,1568.41 +baseline,3,128,8,1,1580.59 +baseline,3,128,8,2,1601.39 +baseline,3,128,8,3,1617.94 +baseline,3,128,8,4,1621.94 +baseline,3,24,512,cold,0.87 +baseline,3,24,512,0,88.733 +baseline,3,24,512,1,89.344 +baseline,3,24,512,2,88.056 +baseline,3,24,512,3,88.628 +baseline,3,24,512,4,88.057 +baseline,3,64,512,cold,4.054 +baseline,3,64,512,0,4316.2 +baseline,3,64,512,1,502.097 +baseline,3,64,512,2,491.085 +baseline,3,64,512,3,481.417 +baseline,3,64,512,4,481.434 +changed,1,12,1,cold,0.222 +changed,1,12,1,0,15.843 +changed,1,12,1,1,15.803 +changed,1,12,1,2,15.832 +changed,1,12,1,3,15.761 +changed,1,12,1,4,15.783 +changed,1,24,8,cold,0.697 +changed,1,24,8,0,61.656 +changed,1,24,8,1,61.677 +changed,1,24,8,2,61.549 +changed,1,24,8,3,61.658 +changed,1,24,8,4,61.75 +changed,1,64,8,cold,2.787 +changed,1,64,8,0,331.36 +changed,1,64,8,1,331.455 +changed,1,64,8,2,330.853 +changed,1,64,8,3,330.686 +changed,1,64,8,4,330.369 +changed,1,128,8,cold,8.038 +changed,1,128,8,0,1021 +changed,1,128,8,1,1018.78 +changed,1,128,8,2,1017.47 +changed,1,128,8,3,1019.36 +changed,1,128,8,4,1019.77 +changed,1,24,512,cold,0.906 +changed,1,24,512,0,63.913 +changed,1,24,512,1,63.857 +changed,1,24,512,2,63.772 +changed,1,24,512,3,63.689 +changed,1,24,512,4,63.836 +changed,1,64,512,cold,4.241 +changed,1,64,512,0,346.794 +changed,1,64,512,1,346.239 +changed,1,64,512,2,346.653 +changed,1,64,512,3,346.084 +changed,1,64,512,4,346.401 +changed,2,12,1,cold,0.228 +changed,2,12,1,0,15.837 +changed,2,12,1,1,15.89 +changed,2,12,1,2,15.812 +changed,2,12,1,3,15.876 +changed,2,12,1,4,15.826 +changed,2,24,8,cold,0.674 +changed,2,24,8,0,62.114 +changed,2,24,8,1,62.061 +changed,2,24,8,2,61.849 +changed,2,24,8,3,61.84 +changed,2,24,8,4,61.964 +changed,2,64,8,cold,2.824 +changed,2,64,8,0,332.358 +changed,2,64,8,1,331.152 +changed,2,64,8,2,330.616 +changed,2,64,8,3,331.223 +changed,2,64,8,4,331.156 +changed,2,128,8,cold,7.945 +changed,2,128,8,0,1024.92 +changed,2,128,8,1,1026.21 +changed,2,128,8,2,1029.4 +changed,2,128,8,3,1028.64 +changed,2,128,8,4,1029.31 +changed,2,24,512,cold,0.87 +changed,2,24,512,0,66.826 +changed,2,24,512,1,66.646 +changed,2,24,512,2,66.689 +changed,2,24,512,3,66.519 +changed,2,24,512,4,66.574 +changed,2,64,512,cold,4.219 +changed,2,64,512,0,353.105 +changed,2,64,512,1,350.961 +changed,2,64,512,2,351.948 +changed,2,64,512,3,349.809 +changed,2,64,512,4,350.014 +changed,3,12,1,cold,0.217 +changed,3,12,1,0,15.886 +changed,3,12,1,1,15.985 +changed,3,12,1,2,16.17 +changed,3,12,1,3,16.055 +changed,3,12,1,4,16.149 +changed,3,24,8,cold,0.666 +changed,3,24,8,0,61.702 +changed,3,24,8,1,61.583 +changed,3,24,8,2,61.616 +changed,3,24,8,3,64.224 +changed,3,24,8,4,64.068 +changed,3,64,8,cold,2.831 +changed,3,64,8,0,341.941 +changed,3,64,8,1,334.288 +changed,3,64,8,2,334.239 +changed,3,64,8,3,334.907 +changed,3,64,8,4,335.666 +changed,3,128,8,cold,7.803 +changed,3,128,8,0,1051.2 +changed,3,128,8,1,1051.09 +changed,3,128,8,2,1067.18 +changed,3,128,8,3,1053.47 +changed,3,128,8,4,1053.51 +changed,3,24,512,cold,0.889 +changed,3,24,512,0,69.879 +changed,3,24,512,1,72.843 +changed,3,24,512,2,72.899 +changed,3,24,512,3,72.69 +changed,3,24,512,4,72.82 +changed,3,64,512,cold,4.36 +changed,3,64,512,0,332.802 +changed,3,64,512,1,333.305 +changed,3,64,512,2,333.076 +changed,3,64,512,3,334.667 +changed,3,64,512,4,333.246 diff --git a/Tools/Benchmarks/FlippedSpritesResults/game-summary.json b/Tools/Benchmarks/FlippedSpritesResults/game-summary.json new file mode 100644 index 0000000000..f6986c5fa1 --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/game-summary.json @@ -0,0 +1,55 @@ +{ + "baseline": [ + { + "pair": 1, + "simulation_mean_us": 2578.5833333333335, + "simulation_p95_us": 8645, + "color_mean_us": 129.39444444444445, + "color_p95_us": 198, + "travel_mean_us": 2073.9555555555557 + }, + { + "pair": 2, + "simulation_mean_us": 2488.016666666667, + "simulation_p95_us": 8072, + "color_mean_us": 125.9888888888889, + "color_p95_us": 186, + "travel_mean_us": 1989.861111111111 + }, + { + "pair": 3, + "simulation_mean_us": 2534.261111111111, + "simulation_p95_us": 8067, + "color_mean_us": 129.41666666666666, + "color_p95_us": 190, + "travel_mean_us": 2015.75 + } + ], + "changed": [ + { + "pair": 1, + "simulation_mean_us": 2499.6444444444446, + "simulation_p95_us": 8196, + "color_mean_us": 102.86666666666666, + "color_p95_us": 155, + "travel_mean_us": 2015.3111111111111 + }, + { + "pair": 2, + "simulation_mean_us": 2497.438888888889, + "simulation_p95_us": 8177, + "color_mean_us": 102.10555555555555, + "color_p95_us": 156, + "travel_mean_us": 2008.95 + }, + { + "pair": 3, + "simulation_mean_us": 2476.483333333333, + "simulation_p95_us": 8160, + "color_mean_us": 101.06111111111112, + "color_p95_us": 155, + "travel_mean_us": 1998.5555555555557 + } + ], + "particles_equal": true +} diff --git a/Tools/Benchmarks/FlippedSpritesResults/game.csv b/Tools/Benchmarks/FlippedSpritesResults/game.csv new file mode 100644 index 0000000000..414e3fd5e8 --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/game.csv @@ -0,0 +1,1441 @@ +variant,pair,tick,simulation_us,movable_us,particles,travel_us,color_us,clear_us,grid_wait_us +baseline,1,0,6026,496,508,0,164,149,0 +baseline,1,1,15303,15240,487,14728,111,7,0 +baseline,1,2,11929,11890,455,11540,119,6,0 +baseline,1,3,9947,9889,412,9456,121,4,0 +baseline,1,4,7418,7369,359,7062,116,4,0 +baseline,1,5,5353,5296,314,4933,113,11,0 +baseline,1,6,4206,4155,274,3860,105,8,0 +baseline,1,7,2974,2913,248,2644,91,9,0 +baseline,1,8,2619,2565,242,2321,90,4,0 +baseline,1,9,2040,1989,256,1784,78,7,1 +baseline,1,10,1812,1721,271,1489,86,5,1 +baseline,1,11,1857,1781,361,1528,96,8,0 +baseline,1,12,1574,1484,372,1171,80,4,1 +baseline,1,13,1596,1515,383,1247,82,4,1 +baseline,1,14,1323,1217,391,1045,74,7,1 +baseline,1,15,1404,1352,390,1032,91,6,0 +baseline,1,16,1277,1169,390,932,84,6,0 +baseline,1,17,1201,1154,393,934,75,5,1 +baseline,1,18,1635,1119,413,881,75,3,3 +baseline,1,19,1175,1079,419,847,74,11,1 +baseline,1,20,1199,1126,429,853,80,13,0 +baseline,1,21,1121,1037,425,808,75,3,0 +baseline,1,22,1091,1026,432,815,70,9,1 +baseline,1,23,1093,1035,451,851,73,3,0 +baseline,1,24,1128,1085,448,835,65,3,1 +baseline,1,25,1156,1074,449,785,80,5,1 +baseline,1,26,1068,1020,443,842,69,4,0 +baseline,1,27,1013,968,433,784,68,3,1 +baseline,1,28,1052,972,434,784,69,7,0 +baseline,1,29,1049,962,424,754,60,4,0 +baseline,1,30,1025,942,416,716,69,3,0 +baseline,1,31,1019,922,409,695,69,5,1 +baseline,1,32,1073,986,401,732,71,3,0 +baseline,1,33,1027,971,392,704,74,5,0 +baseline,1,34,1012,921,385,743,64,9,1 +baseline,1,35,981,932,374,714,65,6,0 +baseline,1,36,1055,890,374,665,67,4,0 +baseline,1,37,958,900,367,667,62,7,0 +baseline,1,38,885,820,362,627,57,5,0 +baseline,1,39,924,851,352,654,61,6,1 +baseline,1,40,924,843,342,645,64,5,0 +baseline,1,41,924,848,309,629,62,4,0 +baseline,1,42,1010,896,283,630,62,4,1 +baseline,1,43,960,813,274,621,66,6,0 +baseline,1,44,915,848,267,660,61,4,0 +baseline,1,45,905,854,267,645,63,4,1 +baseline,1,46,916,872,259,654,63,3,0 +baseline,1,47,879,830,251,645,61,8,0 +baseline,1,48,857,777,240,592,60,10,1 +baseline,1,49,880,769,235,564,55,5,1 +baseline,1,50,868,817,237,642,59,3,0 +baseline,1,51,901,812,245,607,60,3,1 +baseline,1,52,858,777,239,572,57,6,0 +baseline,1,53,865,787,229,599,60,7,0 +baseline,1,54,805,762,221,605,51,4,0 +baseline,1,55,815,767,213,612,65,4,0 +baseline,1,56,874,711,203,560,54,4,0 +baseline,1,57,882,786,200,596,53,8,1 +baseline,1,58,758,707,193,562,53,3,0 +baseline,1,59,851,705,190,541,52,3,0 +baseline,1,60,6593,846,696,525,197,4,1 +baseline,1,61,17419,17339,666,16750,179,4,0 +baseline,1,62,12580,12451,630,12033,167,3,0 +baseline,1,63,10700,10640,580,10201,172,5,1 +baseline,1,64,8645,8582,528,8146,158,4,0 +baseline,1,65,6078,6034,506,5635,148,5,0 +baseline,1,66,4842,4791,489,4441,151,4,0 +baseline,1,67,3920,3865,459,3498,141,4,0 +baseline,1,68,3331,3180,420,2860,138,4,0 +baseline,1,69,2607,2546,397,2270,119,4,0 +baseline,1,70,2379,2314,400,1981,144,4,0 +baseline,1,71,2141,2082,454,1822,141,4,0 +baseline,1,72,1986,1935,468,1687,133,5,1 +baseline,1,73,1940,1891,473,1622,124,18,0 +baseline,1,74,1899,1802,475,1543,115,4,0 +baseline,1,75,1715,1591,486,1348,120,5,0 +baseline,1,76,1713,1659,480,1386,123,3,1 +baseline,1,77,1567,1520,473,1272,112,4,1 +baseline,1,78,1629,1532,470,1196,125,5,0 +baseline,1,79,1586,1509,483,1270,103,5,0 +baseline,1,80,1644,1595,481,1261,134,4,0 +baseline,1,81,1657,1524,490,1257,113,10,0 +baseline,1,82,1631,1549,532,1224,114,14,0 +baseline,1,83,1523,1439,566,1212,109,4,0 +baseline,1,84,1584,1524,587,1227,111,11,0 +baseline,1,85,1435,1332,587,1091,107,5,1 +baseline,1,86,1639,1531,583,1163,128,13,0 +baseline,1,87,1535,1358,572,1065,120,5,1 +baseline,1,88,1399,1356,568,1092,121,3,0 +baseline,1,89,1428,1381,565,1080,98,13,0 +baseline,1,90,1355,1306,554,1016,101,4,1 +baseline,1,91,1822,1310,547,1081,96,5,0 +baseline,1,92,1434,1349,547,1037,108,4,1 +baseline,1,93,1338,1250,533,993,104,5,1 +baseline,1,94,1426,1228,530,1002,90,4,1 +baseline,1,95,1379,1277,564,1050,108,4,0 +baseline,1,96,1413,1363,582,1033,113,5,0 +baseline,1,97,1359,1267,561,1002,102,4,1 +baseline,1,98,1323,1236,545,966,107,4,1 +baseline,1,99,1343,1262,537,958,91,5,1 +baseline,1,100,1370,1185,539,954,104,5,1 +baseline,1,101,1407,1359,534,1112,109,8,0 +baseline,1,102,1372,1324,533,1003,100,16,0 +baseline,1,103,1296,1246,524,987,95,8,0 +baseline,1,104,1328,1279,505,986,94,7,0 +baseline,1,105,1235,1158,488,914,99,4,0 +baseline,1,106,1336,1149,483,891,99,5,0 +baseline,1,107,1274,1224,482,987,97,5,1 +baseline,1,108,1306,1257,472,957,101,10,0 +baseline,1,109,1256,1174,447,909,86,12,0 +baseline,1,110,1210,1163,434,938,90,11,0 +baseline,1,111,1157,1111,420,884,84,3,0 +baseline,1,112,1159,1113,406,880,98,3,0 +baseline,1,113,1283,1077,386,851,86,3,0 +baseline,1,114,1157,1109,369,898,85,4,1 +baseline,1,115,1068,1000,358,806,85,4,0 +baseline,1,116,1103,1032,347,816,94,7,1 +baseline,1,117,1101,1050,342,805,93,15,0 +baseline,1,118,1083,1006,333,809,83,11,0 +baseline,1,119,1284,978,332,768,83,4,0 +baseline,1,120,6996,1081,840,739,211,6,0 +baseline,1,121,17592,17547,811,16954,216,9,0 +baseline,1,122,13018,12970,772,12501,186,4,1 +baseline,1,123,10672,10623,720,10070,200,4,0 +baseline,1,124,8138,8038,655,7548,200,8,0 +baseline,1,125,6558,6362,614,5923,207,4,0 +baseline,1,126,5273,5229,581,4755,186,5,0 +baseline,1,127,3961,3911,579,3459,165,4,0 +baseline,1,128,3308,3242,529,2795,176,6,1 +baseline,1,129,2826,2742,514,2376,147,4,0 +baseline,1,130,2693,2620,514,2237,171,5,1 +baseline,1,131,2311,2264,509,1956,158,9,0 +baseline,1,132,2414,2206,507,1907,150,11,1 +baseline,1,133,2186,2137,504,1779,161,3,0 +baseline,1,134,2095,2042,497,1705,133,10,1 +baseline,1,135,2124,2017,511,1701,175,5,1 +baseline,1,136,2011,1925,537,1631,150,3,1 +baseline,1,137,2062,1981,548,1622,144,6,0 +baseline,1,138,1980,1840,552,1531,155,3,0 +baseline,1,139,2143,2033,565,1634,151,6,1 +baseline,1,140,1982,1902,560,1539,159,9,0 +baseline,1,141,1952,1862,552,1464,145,10,0 +baseline,1,142,1831,1756,557,1458,139,13,0 +baseline,1,143,1854,1814,572,1497,139,4,1 +baseline,1,144,1797,1711,582,1415,129,4,0 +baseline,1,145,1978,1754,586,1380,140,4,0 +baseline,1,146,1751,1692,588,1334,130,5,0 +baseline,1,147,1719,1629,579,1316,141,11,1 +baseline,1,148,1707,1668,590,1326,133,4,0 +baseline,1,149,1796,1708,580,1323,114,9,1 +baseline,1,150,1773,1670,571,1318,147,9,0 +baseline,1,151,1711,1645,565,1324,138,11,0 +baseline,1,152,1853,1647,570,1288,126,3,0 +baseline,1,153,1717,1627,572,1323,124,13,0 +baseline,1,154,1585,1498,561,1227,119,7,0 +baseline,1,155,1583,1491,566,1192,136,5,0 +baseline,1,156,1591,1492,565,1200,132,4,1 +baseline,1,157,1498,1434,550,1167,116,7,0 +baseline,1,158,1572,1391,554,1114,124,3,1 +baseline,1,159,1485,1439,551,1114,116,11,1 +baseline,1,160,1508,1420,540,1122,136,7,0 +baseline,1,161,1520,1441,538,1105,122,6,0 +baseline,1,162,1577,1491,539,1157,120,6,1 +baseline,1,163,1414,1376,532,1119,111,8,0 +baseline,1,164,1954,1319,524,1058,106,3,1 +baseline,1,165,1493,1401,513,1104,126,4,0 +baseline,1,166,1418,1326,492,1064,115,13,1 +baseline,1,167,1465,1391,478,1062,119,15,0 +baseline,1,168,1346,1254,478,1005,107,7,1 +baseline,1,169,1392,1311,462,1034,111,4,0 +baseline,1,170,1424,1376,449,1101,117,8,0 +baseline,1,171,1438,1222,447,981,118,3,2 +baseline,1,172,1337,1290,446,1045,117,3,0 +baseline,1,173,1318,1227,434,973,119,6,1 +baseline,1,174,1274,1192,424,970,99,6,0 +baseline,1,175,1464,1377,435,1015,128,4,1 +baseline,1,176,1277,1223,430,981,100,3,1 +baseline,1,177,1397,1205,444,955,111,3,0 +baseline,1,178,1398,1296,440,990,117,5,2 +baseline,1,179,1306,1156,438,919,105,3,0 +baseline,1,180,6457,1239,883,823,231,4,0 +baseline,1,181,16226,16173,860,15492,210,14,1 +baseline,1,182,11904,11868,804,11397,202,3,0 +baseline,1,183,9561,9493,742,9040,200,4,1 +baseline,1,184,7653,7465,696,6996,184,9,0 +baseline,1,185,5909,5844,656,5425,198,5,1 +baseline,1,186,4702,4616,625,4209,169,4,0 +baseline,1,187,3641,3583,584,3126,162,4,0 +baseline,1,188,2840,2760,553,2454,152,8,1 +baseline,1,189,2924,2835,526,2421,150,4,1 +baseline,1,190,2514,2427,510,2096,157,3,0 +baseline,1,191,2528,2377,501,2011,148,3,0 +baseline,1,192,2140,2053,488,1741,140,9,0 +baseline,1,193,2126,2039,498,1680,157,3,1 +baseline,1,194,2022,1936,504,1626,135,4,0 +baseline,1,195,2024,1929,496,1571,157,6,1 +baseline,1,196,1867,1821,480,1518,148,3,0 +baseline,1,197,1904,1858,469,1460,129,3,0 +baseline,1,198,1890,1712,477,1414,143,3,0 +baseline,1,199,1805,1737,469,1443,124,9,1 +baseline,1,200,1696,1645,461,1348,141,4,0 +baseline,1,201,1670,1580,454,1273,129,7,0 +baseline,1,202,1640,1541,447,1245,134,4,1 +baseline,1,203,1565,1517,440,1244,139,3,0 +baseline,1,204,1655,1590,431,1222,125,5,0 +baseline,1,205,1658,1446,423,1127,143,4,0 +baseline,1,206,1574,1483,404,1220,129,7,0 +baseline,1,207,1623,1519,401,1177,135,3,1 +baseline,1,208,1531,1433,419,1152,129,7,1 +baseline,1,209,1521,1475,420,1162,123,4,0 +baseline,1,210,1602,1540,416,1193,136,3,1 +baseline,1,211,1588,1407,406,1100,129,4,1 +baseline,1,212,1473,1428,410,1178,114,7,0 +baseline,1,213,1404,1345,411,1075,122,8,0 +baseline,1,214,1470,1371,406,1070,121,10,0 +baseline,1,215,1527,1431,401,1086,138,9,1 +baseline,1,216,1505,1409,389,1068,116,8,1 +baseline,1,217,1656,1412,379,1020,123,4,1 +baseline,1,218,1433,1363,377,1048,113,14,1 +baseline,1,219,1376,1271,374,1007,113,3,1 +baseline,1,220,1298,1222,374,973,128,9,1 +baseline,1,221,1406,1360,366,1013,109,4,0 +baseline,1,222,1317,1224,363,969,104,14,0 +baseline,1,223,1330,1249,357,975,123,2,0 +baseline,1,224,1442,1270,355,1028,110,2,0 +baseline,1,225,1336,1263,357,1005,110,4,1 +baseline,1,226,1339,1257,363,996,116,3,0 +baseline,1,227,1318,1211,367,957,104,4,1 +baseline,1,228,1379,1335,355,1008,113,6,1 +baseline,1,229,1296,1215,350,959,98,6,0 +baseline,1,230,1433,1334,345,935,127,4,1 +baseline,1,231,1424,1185,345,915,104,3,0 +baseline,1,232,1238,1164,340,928,105,6,0 +baseline,1,233,1234,1186,339,941,110,3,0 +baseline,1,234,1270,1218,331,963,109,13,1 +baseline,1,235,1297,1244,331,973,118,5,0 +baseline,1,236,1268,1212,325,942,112,4,0 +baseline,1,237,1543,1075,314,837,100,2,1 +baseline,1,238,1360,1117,294,846,106,3,0 +baseline,1,239,1275,1124,290,838,94,3,1 +baseline,2,0,6619,558,508,1,153,178,0 +baseline,2,1,15386,15343,487,14859,109,3,0 +baseline,2,2,11481,11435,455,11028,117,3,0 +baseline,2,3,9747,9701,412,9248,119,3,0 +baseline,2,4,7186,7135,359,6816,111,5,0 +baseline,2,5,5508,5444,314,5066,109,12,0 +baseline,2,6,4182,4115,274,3816,95,6,0 +baseline,2,7,2936,2886,248,2624,97,9,1 +baseline,2,8,2613,2524,242,2302,94,4,0 +baseline,2,9,2012,1945,256,1667,86,4,0 +baseline,2,10,1743,1651,271,1450,81,8,1 +baseline,2,11,1680,1583,361,1364,84,6,0 +baseline,2,12,1479,1414,372,1211,73,8,1 +baseline,2,13,1432,1332,383,1123,74,4,0 +baseline,2,14,1302,1242,391,1039,68,12,1 +baseline,2,15,1210,1134,390,946,74,3,2 +baseline,2,16,1222,1117,390,909,80,4,2 +baseline,2,17,1233,1176,393,932,78,4,0 +baseline,2,18,1210,1124,413,881,76,3,0 +baseline,2,19,1130,1036,419,835,67,15,0 +baseline,2,20,1145,1070,429,882,67,5,1 +baseline,2,21,1106,1055,425,862,71,14,0 +baseline,2,22,1141,1041,432,813,75,4,1 +baseline,2,23,1224,1138,451,881,68,9,0 +baseline,2,24,1127,1079,448,832,66,4,0 +baseline,2,25,1075,994,449,766,65,12,0 +baseline,2,26,1116,1011,443,754,64,5,1 +baseline,2,27,1044,947,433,741,63,5,1 +baseline,2,28,1179,1089,434,755,77,9,0 +baseline,2,29,1041,994,424,738,61,7,0 +baseline,2,30,1025,961,416,709,72,7,1 +baseline,2,31,1016,957,409,685,68,4,0 +baseline,2,32,967,902,401,698,62,8,0 +baseline,2,33,1045,958,392,704,67,4,4 +baseline,2,34,1022,918,385,673,67,4,1 +baseline,2,35,1035,908,374,654,69,3,0 +baseline,2,36,1006,912,374,696,63,13,0 +baseline,2,37,914,830,367,639,61,7,0 +baseline,2,38,898,823,362,646,56,4,0 +baseline,2,39,912,832,352,623,57,4,0 +baseline,2,40,923,861,342,634,68,4,0 +baseline,2,41,941,825,309,603,58,4,0 +baseline,2,42,848,766,283,597,56,4,0 +baseline,2,43,907,859,274,662,61,4,1 +baseline,2,44,952,892,267,620,62,12,0 +baseline,2,45,929,867,267,624,71,6,0 +baseline,2,46,1001,934,259,654,71,9,0 +baseline,2,47,918,826,251,590,71,4,0 +baseline,2,48,1043,975,240,660,70,5,1 +baseline,2,49,906,843,235,600,64,6,1 +baseline,2,50,958,879,237,585,71,5,1 +baseline,2,51,920,848,245,609,68,5,0 +baseline,2,52,878,813,239,586,66,4,1 +baseline,2,53,851,800,229,640,56,11,0 +baseline,2,54,1059,876,221,597,62,3,0 +baseline,2,55,931,829,213,611,62,4,1 +baseline,2,56,837,765,203,568,56,4,0 +baseline,2,57,948,839,200,577,56,7,0 +baseline,2,58,842,745,193,545,55,3,0 +baseline,2,59,889,775,190,555,55,4,0 +baseline,2,60,6322,815,696,481,199,4,0 +baseline,2,61,16203,16133,666,15544,183,5,0 +baseline,2,62,11670,11629,630,11196,167,8,0 +baseline,2,63,10178,10134,580,9645,170,7,0 +baseline,2,64,8072,8011,528,7570,164,8,0 +baseline,2,65,5566,5503,506,5135,157,4,0 +baseline,2,66,4704,4564,489,4135,154,4,0 +baseline,2,67,3752,3709,459,3336,134,6,1 +baseline,2,68,3199,3148,420,2724,138,4,0 +baseline,2,69,2537,2494,397,2097,112,4,0 +baseline,2,70,2201,2145,400,1835,132,3,1 +baseline,2,71,2118,2071,454,1700,134,12,1 +baseline,2,72,1973,1917,468,1621,128,10,0 +baseline,2,73,2023,1844,473,1508,124,4,0 +baseline,2,74,1742,1700,475,1433,110,7,0 +baseline,2,75,1643,1574,486,1274,115,4,0 +baseline,2,76,1543,1479,480,1218,125,3,1 +baseline,2,77,1527,1471,473,1187,115,9,0 +baseline,2,78,1567,1484,470,1161,116,4,0 +baseline,2,79,1579,1436,483,1171,106,4,0 +baseline,2,80,1467,1418,481,1165,113,4,0 +baseline,2,81,1500,1410,490,1131,124,3,0 +baseline,2,82,1532,1440,532,1192,106,6,1 +baseline,2,83,1511,1439,566,1142,116,4,0 +baseline,2,84,1493,1395,587,1093,100,4,1 +baseline,2,85,1329,1279,587,1039,105,7,0 +baseline,2,86,1472,1264,583,997,104,4,0 +baseline,2,87,1427,1333,572,1023,107,16,0 +baseline,2,88,1312,1224,568,983,104,6,0 +baseline,2,89,1368,1260,565,993,101,4,0 +baseline,2,90,1302,1222,554,968,103,4,0 +baseline,2,91,1300,1243,547,976,103,5,0 +baseline,2,92,1406,1197,547,973,107,4,1 +baseline,2,93,1373,1266,533,997,98,4,0 +baseline,2,94,1399,1305,530,1032,90,5,0 +baseline,2,95,1293,1219,564,985,101,4,1 +baseline,2,96,1255,1198,582,966,101,8,0 +baseline,2,97,1247,1168,561,918,90,3,0 +baseline,2,98,1234,1167,545,909,104,3,0 +baseline,2,99,1360,1167,537,933,89,4,0 +baseline,2,100,1277,1227,539,941,95,14,0 +baseline,2,101,1268,1191,534,918,99,4,0 +baseline,2,102,1321,1234,533,899,99,10,0 +baseline,2,103,1247,1140,524,888,92,9,1 +baseline,2,104,1268,1175,505,925,90,4,0 +baseline,2,105,1291,1108,488,856,94,4,0 +baseline,2,106,1209,1132,483,901,97,4,0 +baseline,2,107,1206,1139,482,852,88,4,1 +baseline,2,108,1175,1092,472,851,87,4,0 +baseline,2,109,1145,1098,447,878,78,3,0 +baseline,2,110,1186,1087,434,816,88,4,1 +baseline,2,111,1647,1011,420,789,96,3,1 +baseline,2,112,1217,1136,406,863,85,4,1 +baseline,2,113,1142,1059,386,802,85,4,0 +baseline,2,114,1131,1092,369,825,77,6,0 +baseline,2,115,1044,992,358,789,83,4,0 +baseline,2,116,1088,1019,347,758,95,4,0 +baseline,2,117,1081,1020,342,767,90,7,1 +baseline,2,118,1134,939,333,711,84,3,1 +baseline,2,119,1234,1121,332,810,76,12,0 +baseline,2,120,6717,1033,840,670,205,4,0 +baseline,2,121,16461,16389,811,15780,218,4,0 +baseline,2,122,11991,11951,772,11460,194,5,0 +baseline,2,123,10004,9964,720,9402,192,56,0 +baseline,2,124,7611,7470,655,6977,173,4,0 +baseline,2,125,5874,5831,614,5387,192,4,0 +baseline,2,126,4927,4881,581,4480,162,6,0 +baseline,2,127,3789,3734,579,3338,155,4,1 +baseline,2,128,3086,3050,529,2724,150,3,0 +baseline,2,129,2843,2784,514,2363,164,8,0 +baseline,2,130,2520,2472,514,2151,158,3,0 +baseline,2,131,2432,2230,509,1881,147,3,0 +baseline,2,132,2282,2242,507,1883,145,3,0 +baseline,2,133,2085,2004,504,1678,151,7,0 +baseline,2,134,2070,1967,497,1671,141,5,0 +baseline,2,135,2053,1954,511,1647,150,8,0 +baseline,2,136,1986,1931,537,1630,158,9,0 +baseline,2,137,2072,1918,548,1610,152,3,1 +baseline,2,138,1984,1906,552,1517,151,14,0 +baseline,2,139,1977,1934,565,1607,135,6,0 +baseline,2,140,1870,1782,560,1470,150,4,0 +baseline,2,141,1822,1743,552,1446,131,6,1 +baseline,2,142,1924,1815,557,1490,138,8,2 +baseline,2,143,1900,1833,572,1464,139,6,0 +baseline,2,144,1918,1693,582,1390,121,3,0 +baseline,2,145,1786,1724,586,1382,135,3,0 +baseline,2,146,1652,1591,588,1312,126,4,0 +baseline,2,147,1688,1643,579,1313,123,7,0 +baseline,2,148,1672,1604,590,1321,123,17,0 +baseline,2,149,1672,1580,580,1265,125,14,1 +baseline,2,150,1788,1612,571,1278,142,4,0 +baseline,2,151,1691,1636,565,1308,127,9,1 +baseline,2,152,1632,1570,570,1249,123,3,1 +baseline,2,153,1655,1601,572,1261,135,5,1 +baseline,2,154,1521,1438,561,1169,124,4,1 +baseline,2,155,1547,1457,566,1186,127,7,0 +baseline,2,156,1623,1468,565,1155,123,4,2 +baseline,2,157,1574,1499,550,1170,123,6,0 +baseline,2,158,1464,1405,554,1130,125,4,0 +baseline,2,159,1530,1487,551,1210,116,6,0 +baseline,2,160,1588,1519,540,1155,133,5,0 +baseline,2,161,1486,1408,538,1109,132,14,0 +baseline,2,162,1430,1362,539,1089,122,13,0 +baseline,2,163,1554,1350,532,1065,122,4,0 +baseline,2,164,1495,1425,524,1094,107,9,0 +baseline,2,165,1408,1329,513,1052,133,5,1 +baseline,2,166,1401,1345,492,1076,107,5,0 +baseline,2,167,1410,1322,478,1001,113,10,0 +baseline,2,168,1377,1286,478,1013,111,9,1 +baseline,2,169,1441,1303,462,996,101,4,1 +baseline,2,170,1406,1302,449,1012,126,10,1 +baseline,2,171,1363,1318,447,1070,116,8,0 +baseline,2,172,1337,1248,446,979,110,3,1 +baseline,2,173,1338,1239,434,950,115,3,1 +baseline,2,174,1285,1202,424,964,98,4,0 +baseline,2,175,1422,1340,435,995,126,4,0 +baseline,2,176,1422,1210,430,952,102,4,0 +baseline,2,177,1297,1215,444,952,110,3,0 +baseline,2,178,1277,1197,440,937,114,4,1 +baseline,2,179,1221,1118,438,888,99,3,1 +baseline,2,180,6648,1274,883,838,204,5,0 +baseline,2,181,16138,16064,860,15474,208,14,0 +baseline,2,182,12189,12043,804,11542,186,3,0 +baseline,2,183,9548,9496,742,9019,186,2,0 +baseline,2,184,7854,7415,696,6995,167,7,1 +baseline,2,185,5910,5870,656,5465,192,3,0 +baseline,2,186,4646,4572,625,4098,180,4,0 +baseline,2,187,3549,3485,584,3097,160,6,1 +baseline,2,188,2878,2740,553,2423,149,3,0 +baseline,2,189,2644,2555,526,2261,136,10,1 +baseline,2,190,2523,2436,510,2099,159,4,1 +baseline,2,191,2411,2354,501,1975,153,6,0 +baseline,2,192,2148,2058,488,1752,141,3,1 +baseline,2,193,2056,1967,498,1659,139,7,0 +baseline,2,194,2074,1975,504,1662,136,10,0 +baseline,2,195,2112,1891,496,1545,142,3,0 +baseline,2,196,1874,1787,480,1483,146,9,1 +baseline,2,197,1787,1706,469,1390,136,4,1 +baseline,2,198,1891,1802,477,1400,145,4,0 +baseline,2,199,1776,1696,469,1327,130,3,1 +baseline,2,200,1738,1662,461,1284,149,3,0 +baseline,2,201,1686,1606,454,1284,132,4,0 +baseline,2,202,1641,1433,447,1170,127,3,0 +baseline,2,203,1666,1570,440,1253,138,8,1 +baseline,2,204,1565,1480,431,1223,112,9,3 +baseline,2,205,1554,1459,423,1169,141,4,1 +baseline,2,206,1567,1483,404,1153,128,3,0 +baseline,2,207,1584,1484,401,1152,124,5,1 +baseline,2,208,1510,1442,419,1183,125,7,0 +baseline,2,209,1509,1347,420,1092,125,4,1 +baseline,2,210,1612,1505,416,1167,131,5,1 +baseline,2,211,1445,1392,406,1097,122,7,0 +baseline,2,212,1409,1335,410,1084,120,10,0 +baseline,2,213,1522,1436,411,1089,128,8,1 +baseline,2,214,1396,1306,406,1060,114,4,0 +baseline,2,215,1557,1330,401,1064,132,3,1 +baseline,2,216,1451,1362,389,1094,120,13,0 +baseline,2,217,1328,1237,379,986,112,12,0 +baseline,2,218,1282,1199,377,971,110,3,0 +baseline,2,219,1334,1254,374,1007,113,3,1 +baseline,2,220,1317,1244,374,1000,117,6,1 +baseline,2,221,1411,1345,366,1027,111,4,0 +baseline,2,222,1390,1210,363,940,126,3,0 +baseline,2,223,1366,1269,357,972,118,3,1 +baseline,2,224,1361,1294,355,1014,106,10,0 +baseline,2,225,1282,1208,357,958,115,2,0 +baseline,2,226,1251,1211,363,964,116,3,0 +baseline,2,227,1301,1224,367,953,102,4,1 +baseline,2,228,1584,1228,355,971,114,4,0 +baseline,2,229,1331,1233,350,952,97,9,0 +baseline,2,230,1261,1157,345,925,113,3,0 +baseline,2,231,1267,1153,345,900,113,7,1 +baseline,2,232,1239,1184,340,917,107,4,1 +baseline,2,233,1219,1132,339,887,105,7,2 +baseline,2,234,1371,1164,331,913,100,3,0 +baseline,2,235,1248,1152,331,903,110,8,0 +baseline,2,236,1297,1216,325,874,119,7,1 +baseline,2,237,1223,1139,314,870,103,4,0 +baseline,2,238,1255,1188,294,868,101,6,1 +baseline,2,239,1196,1104,290,882,94,6,0 +baseline,3,0,6580,557,508,0,162,167,0 +baseline,3,1,15379,15328,487,14785,105,4,0 +baseline,3,2,11463,11423,455,10991,114,7,0 +baseline,3,3,9757,9720,412,9315,121,3,0 +baseline,3,4,7587,7527,359,7144,112,4,0 +baseline,3,5,5360,5310,314,4948,107,10,0 +baseline,3,6,4285,4222,274,3808,101,9,0 +baseline,3,7,3009,2939,248,2631,97,4,0 +baseline,3,8,2701,2642,242,2345,87,5,0 +baseline,3,9,2038,1988,256,1754,75,4,1 +baseline,3,10,1825,1724,271,1460,84,4,1 +baseline,3,11,1680,1598,361,1362,83,13,0 +baseline,3,12,1483,1384,372,1178,71,5,0 +baseline,3,13,1431,1349,383,1127,77,4,0 +baseline,3,14,1418,1320,391,1031,72,4,0 +baseline,3,15,1289,1172,390,939,81,4,0 +baseline,3,16,1152,1110,390,904,74,3,0 +baseline,3,17,1134,1069,393,872,70,5,0 +baseline,3,18,1220,1131,413,903,75,4,0 +baseline,3,19,1209,1167,419,935,73,6,0 +baseline,3,20,1081,1030,429,845,70,4,1 +baseline,3,21,1243,1170,425,859,87,6,0 +baseline,3,22,1219,1123,432,883,74,21,1 +baseline,3,23,1197,1134,451,879,77,5,0 +baseline,3,24,1070,1019,448,799,69,9,1 +baseline,3,25,1152,1040,449,802,79,10,1 +baseline,3,26,1153,1048,443,809,77,10,0 +baseline,3,27,1047,968,433,727,66,4,1 +baseline,3,28,1111,1017,434,736,63,9,0 +baseline,3,29,1083,1014,424,812,65,8,0 +baseline,3,30,1072,983,416,728,72,6,1 +baseline,3,31,1005,921,409,672,73,4,0 +baseline,3,32,970,895,401,687,61,4,1 +baseline,3,33,991,903,392,689,71,9,2 +baseline,3,34,1091,1007,385,730,67,5,0 +baseline,3,35,1032,884,374,643,64,4,0 +baseline,3,36,919,857,374,677,61,6,0 +baseline,3,37,933,854,367,641,65,4,1 +baseline,3,38,897,845,362,668,58,7,1 +baseline,3,39,915,842,352,640,59,7,1 +baseline,3,40,910,811,342,628,58,4,1 +baseline,3,41,929,853,309,627,61,14,0 +baseline,3,42,926,806,283,600,62,7,0 +baseline,3,43,907,817,274,588,63,10,1 +baseline,3,44,879,792,267,610,59,8,1 +baseline,3,45,786,734,267,578,72,4,1 +baseline,3,46,947,882,259,650,64,8,1 +baseline,3,47,869,777,251,578,58,4,0 +baseline,3,48,882,743,240,550,58,7,1 +baseline,3,49,839,760,235,558,53,9,1 +baseline,3,50,800,738,237,559,62,5,0 +baseline,3,51,778,725,245,580,60,4,0 +baseline,3,52,837,768,239,564,56,4,0 +baseline,3,53,861,785,229,589,56,12,0 +baseline,3,54,812,725,221,554,52,7,1 +baseline,3,55,951,751,213,551,56,4,0 +baseline,3,56,876,780,203,568,58,4,0 +baseline,3,57,842,779,200,569,56,4,0 +baseline,3,58,785,721,193,526,53,3,0 +baseline,3,59,898,779,190,521,49,3,0 +baseline,3,60,6264,787,696,470,182,3,0 +baseline,3,61,16159,16068,666,15539,173,8,0 +baseline,3,62,12004,11870,630,11416,163,3,0 +baseline,3,63,9957,9902,580,9410,165,3,0 +baseline,3,64,8067,8002,528,7550,152,4,0 +baseline,3,65,5631,5588,506,5207,153,7,1 +baseline,3,66,4574,4517,489,4149,140,3,0 +baseline,3,67,3785,3746,459,3371,126,4,0 +baseline,3,68,3169,3023,420,2640,128,4,0 +baseline,3,69,2482,2427,397,2095,110,6,0 +baseline,3,70,2291,2201,400,1814,136,4,1 +baseline,3,71,2050,1982,454,1690,122,8,0 +baseline,3,72,1972,1887,468,1590,124,6,1 +baseline,3,73,1967,1879,473,1504,129,4,0 +baseline,3,74,1903,1737,475,1417,109,4,1 +baseline,3,75,1706,1609,486,1295,124,5,0 +baseline,3,76,1623,1552,480,1236,116,17,0 +baseline,3,77,1554,1469,473,1194,109,8,0 +baseline,3,78,1533,1452,470,1166,115,4,0 +baseline,3,79,1508,1455,483,1164,96,4,1 +baseline,3,80,1603,1429,481,1160,121,4,0 +baseline,3,81,1506,1428,490,1125,105,4,1 +baseline,3,82,1516,1430,532,1174,109,4,0 +baseline,3,83,1574,1497,566,1170,110,8,1 +baseline,3,84,1492,1442,587,1134,102,4,0 +baseline,3,85,1423,1319,587,1051,104,6,0 +baseline,3,86,1409,1360,583,1104,114,4,0 +baseline,3,87,1425,1264,572,983,98,10,0 +baseline,3,88,1445,1361,568,1022,108,4,1 +baseline,3,89,1320,1245,565,990,106,5,1 +baseline,3,90,2300,2171,554,1698,181,8,1 +baseline,3,91,2034,1843,547,1448,143,8,0 +baseline,3,92,1663,1546,547,1127,124,5,0 +baseline,3,93,1580,1509,533,1059,145,6,0 +baseline,3,94,1362,1300,530,1053,99,12,0 +baseline,3,95,1391,1329,564,1087,101,5,1 +baseline,3,96,1367,1190,582,951,103,7,0 +baseline,3,97,1205,1154,561,903,96,4,0 +baseline,3,98,1381,1313,545,1034,106,4,1 +baseline,3,99,1433,1376,537,1034,100,5,0 +baseline,3,100,1318,1219,539,923,106,5,0 +baseline,3,101,1303,1222,534,946,92,11,1 +baseline,3,102,1397,1190,533,941,103,4,0 +baseline,3,103,1289,1221,524,901,100,18,0 +baseline,3,104,1284,1184,505,879,98,12,1 +baseline,3,105,1225,1127,488,853,86,4,2 +baseline,3,106,1280,1170,483,859,95,4,0 +baseline,3,107,1270,1190,482,880,84,5,0 +baseline,3,108,1229,1163,472,904,100,15,0 +baseline,3,109,1297,1092,447,806,79,4,0 +baseline,3,110,1222,1161,434,857,107,4,0 +baseline,3,111,1612,1109,420,829,99,6,1 +baseline,3,112,1250,1138,406,849,102,5,0 +baseline,3,113,1219,1102,386,812,99,5,0 +baseline,3,114,1136,1026,369,770,88,5,2 +baseline,3,115,1156,937,358,743,83,5,0 +baseline,3,116,1133,1072,347,805,103,5,0 +baseline,3,117,1095,1039,342,775,104,4,1 +baseline,3,118,1095,977,333,751,87,6,1 +baseline,3,119,1065,936,332,733,86,3,1 +baseline,3,120,6293,1074,840,678,235,5,1 +baseline,3,121,17152,16933,811,16254,218,8,1 +baseline,3,122,12062,11991,772,11420,198,9,1 +baseline,3,123,10874,10792,720,10246,211,4,2 +baseline,3,124,7833,7725,655,7144,208,5,1 +baseline,3,125,6410,6310,614,5822,196,11,0 +baseline,3,126,5027,4924,581,4500,192,5,1 +baseline,3,127,4339,4113,579,3652,176,4,0 +baseline,3,128,3285,3194,529,2790,180,9,0 +baseline,3,129,2743,2659,514,2341,157,6,1 +baseline,3,130,2633,2531,514,2149,178,5,0 +baseline,3,131,2342,2245,509,1904,165,6,0 +baseline,3,132,2313,2241,507,1865,157,7,1 +baseline,3,133,2162,2072,504,1676,154,3,1 +baseline,3,134,2098,1895,497,1615,156,3,0 +baseline,3,135,2141,2073,511,1661,163,8,1 +baseline,3,136,2039,1955,537,1582,155,4,1 +baseline,3,137,2066,1991,548,1610,149,7,0 +baseline,3,138,2072,1977,552,1665,150,4,0 +baseline,3,139,2297,2222,565,1894,140,4,1 +baseline,3,140,2353,2227,560,1871,144,8,1 +baseline,3,141,1899,1800,552,1439,147,3,1 +baseline,3,142,1870,1811,557,1468,135,14,1 +baseline,3,143,1842,1783,572,1450,146,11,0 +baseline,3,144,1724,1645,582,1355,129,4,0 +baseline,3,145,1895,1841,586,1449,161,4,0 +baseline,3,146,1690,1638,588,1322,142,3,0 +baseline,3,147,1780,1549,579,1248,130,4,0 +baseline,3,148,1837,1748,590,1350,130,9,0 +baseline,3,149,1662,1563,580,1243,118,3,0 +baseline,3,150,1675,1608,571,1264,143,4,1 +baseline,3,151,1596,1512,565,1242,131,4,0 +baseline,3,152,1583,1515,570,1235,124,4,0 +baseline,3,153,1588,1491,572,1210,140,5,1 +baseline,3,154,1725,1458,561,1151,124,4,1 +baseline,3,155,1629,1528,566,1177,143,8,0 +baseline,3,156,1903,1811,565,1519,128,5,1 +baseline,3,157,1583,1503,550,1221,127,4,0 +baseline,3,158,1530,1446,554,1118,132,10,0 +baseline,3,159,1436,1391,551,1136,113,4,1 +baseline,3,160,1856,1677,540,1324,136,5,1 +baseline,3,161,1801,1721,538,1394,127,4,0 +baseline,3,162,1447,1374,539,1064,111,3,1 +baseline,3,163,1564,1473,532,1097,120,10,1 +baseline,3,164,1458,1370,524,1064,106,13,0 +baseline,3,165,1432,1346,513,1059,128,11,0 +baseline,3,166,1559,1316,492,1002,116,4,1 +baseline,3,167,1320,1264,478,1005,115,3,1 +baseline,3,168,1334,1252,478,991,115,3,1 +baseline,3,169,1484,1439,462,1100,109,4,0 +baseline,3,170,1370,1266,449,976,123,11,1 +baseline,3,171,1352,1245,447,984,115,5,2 +baseline,3,172,1416,1368,446,1036,117,5,0 +baseline,3,173,1417,1221,434,920,109,6,0 +baseline,3,174,1325,1215,424,971,105,5,1 +baseline,3,175,1407,1303,435,986,117,6,0 +baseline,3,176,1363,1260,430,967,108,6,1 +baseline,3,177,1284,1194,444,938,111,4,0 +baseline,3,178,1264,1209,440,962,106,5,1 +baseline,3,179,1439,1126,438,880,97,3,1 +baseline,3,180,6594,1244,883,828,226,4,1 +baseline,3,181,16287,16215,860,15576,191,16,0 +baseline,3,182,11837,11787,804,11296,176,4,1 +baseline,3,183,9604,9547,742,9065,189,6,1 +baseline,3,184,7812,7355,696,6936,190,5,0 +baseline,3,185,6004,5857,656,5428,190,3,1 +baseline,3,186,4705,4613,625,4156,168,4,1 +baseline,3,187,3595,3508,584,3101,147,10,0 +baseline,3,188,2926,2848,553,2461,178,7,0 +baseline,3,189,2742,2649,526,2295,149,5,0 +baseline,3,190,2526,2462,510,2124,156,6,1 +baseline,3,191,2424,2333,501,1969,146,4,1 +baseline,3,192,2256,2111,488,1754,137,5,0 +baseline,3,193,2123,2058,498,1666,130,4,0 +baseline,3,194,1948,1869,504,1564,126,4,0 +baseline,3,195,1962,1869,496,1549,150,3,1 +baseline,3,196,1872,1778,480,1452,140,14,1 +baseline,3,197,1810,1760,469,1433,147,4,0 +baseline,3,198,1857,1683,477,1378,145,14,0 +baseline,3,199,1718,1608,469,1333,129,4,0 +baseline,3,200,1801,1698,461,1313,138,3,0 +baseline,3,201,1692,1645,454,1305,144,3,0 +baseline,3,202,1544,1456,447,1188,128,10,0 +baseline,3,203,1603,1506,440,1187,142,3,1 +baseline,3,204,1581,1479,431,1181,115,4,1 +baseline,3,205,1671,1411,423,1125,141,4,1 +baseline,3,206,1581,1497,404,1193,129,11,1 +baseline,3,207,1486,1413,401,1131,125,7,1 +baseline,3,208,1641,1546,419,1177,124,6,1 +baseline,3,209,1533,1434,420,1122,120,3,1 +baseline,3,210,1475,1414,416,1137,140,5,0 +baseline,3,211,1529,1471,406,1188,119,3,0 +baseline,3,212,1566,1342,410,1051,126,4,1 +baseline,3,213,1429,1331,411,1073,115,5,1 +baseline,3,214,1485,1374,406,1037,114,4,1 +baseline,3,215,1372,1299,401,1033,123,7,0 +baseline,3,216,1378,1302,389,1029,118,7,1 +baseline,3,217,1328,1232,379,996,121,4,0 +baseline,3,218,1383,1196,377,942,124,3,1 +baseline,3,219,1279,1194,374,944,109,3,0 +baseline,3,220,1310,1220,374,959,122,4,0 +baseline,3,221,1317,1222,366,946,124,4,1 +baseline,3,222,1269,1204,363,956,113,6,0 +baseline,3,223,1271,1206,357,948,115,4,0 +baseline,3,224,1276,1215,355,973,102,4,0 +baseline,3,225,1465,1272,357,999,120,4,0 +baseline,3,226,1342,1241,363,959,114,10,0 +baseline,3,227,1360,1288,367,963,102,3,0 +baseline,3,228,1316,1231,355,937,115,4,0 +baseline,3,229,1267,1179,350,898,95,10,0 +baseline,3,230,1290,1195,345,914,117,7,2 +baseline,3,231,1408,1172,345,898,113,3,1 +baseline,3,232,1297,1221,340,914,109,3,1 +baseline,3,233,1179,1124,339,889,107,7,0 +baseline,3,234,1155,1089,331,860,94,2,0 +baseline,3,235,1228,1148,331,914,122,4,0 +baseline,3,236,1245,1190,325,967,109,14,0 +baseline,3,237,1275,1165,314,869,111,5,0 +baseline,3,238,1361,1119,294,829,103,3,0 +baseline,3,239,1201,1055,290,831,99,3,0 +changed,1,0,6657,521,508,1,134,162,0 +changed,1,1,15610,15565,487,15007,100,9,0 +changed,1,2,11784,11744,455,11386,104,7,1 +changed,1,3,9853,9814,412,9443,109,4,0 +changed,1,4,7431,7362,359,7038,105,6,1 +changed,1,5,5410,5364,314,5009,99,7,0 +changed,1,6,4163,4113,274,3806,87,12,1 +changed,1,7,3004,2921,248,2614,88,3,0 +changed,1,8,2630,2536,242,2305,79,13,0 +changed,1,9,2006,1919,256,1655,70,4,0 +changed,1,10,1760,1709,271,1468,74,4,1 +changed,1,11,1791,1732,361,1498,71,3,1 +changed,1,12,1470,1400,372,1206,62,6,0 +changed,1,13,1507,1438,383,1175,76,6,0 +changed,1,14,1385,1325,391,1076,71,6,0 +changed,1,15,1360,1295,390,1015,80,4,0 +changed,1,16,1186,1138,390,953,67,4,1 +changed,1,17,1262,1118,393,874,69,4,0 +changed,1,18,1163,1088,413,884,63,15,0 +changed,1,19,1298,1247,419,950,67,4,0 +changed,1,20,1221,1127,429,871,65,5,1 +changed,1,21,1092,1016,425,829,67,3,0 +changed,1,22,1119,1075,432,859,62,4,0 +changed,1,23,1098,997,451,797,61,4,0 +changed,1,24,1055,1007,448,806,61,4,1 +changed,1,25,1106,1002,449,793,66,4,0 +changed,1,26,1081,990,443,752,63,9,1 +changed,1,27,1046,980,433,759,62,7,0 +changed,1,28,1035,987,434,789,56,8,5 +changed,1,29,1048,1001,424,778,55,5,0 +changed,1,30,1032,957,416,750,60,7,1 +changed,1,31,1013,913,409,681,56,4,0 +changed,1,32,1067,1022,401,739,59,14,0 +changed,1,33,1006,919,392,659,56,4,1 +changed,1,34,921,876,385,701,61,4,0 +changed,1,35,1051,957,374,665,60,7,1 +changed,1,36,1036,878,374,673,54,3,0 +changed,1,37,971,880,367,671,62,3,1 +changed,1,38,899,815,362,633,49,3,0 +changed,1,39,930,887,352,638,51,4,1 +changed,1,40,990,918,342,634,57,3,0 +changed,1,41,899,810,309,623,54,4,0 +changed,1,42,964,820,283,590,48,3,1 +changed,1,43,911,807,274,623,53,4,1 +changed,1,44,866,816,267,632,48,4,0 +changed,1,45,881,790,267,597,58,3,1 +changed,1,46,875,822,259,577,52,4,0 +changed,1,47,878,802,251,573,61,6,0 +changed,1,48,885,832,240,635,46,4,0 +changed,1,49,889,754,235,553,46,6,0 +changed,1,50,823,777,237,608,52,3,0 +changed,1,51,877,827,245,611,57,9,0 +changed,1,52,795,720,239,563,46,3,0 +changed,1,53,842,745,229,595,47,3,1 +changed,1,54,848,799,221,582,45,4,0 +changed,1,55,841,743,213,564,47,11,0 +changed,1,56,880,742,203,569,42,6,0 +changed,1,57,864,799,200,641,47,3,0 +changed,1,58,883,808,193,552,43,8,0 +changed,1,59,896,795,190,598,39,8,0 +changed,1,60,6510,764,696,475,162,4,0 +changed,1,61,16744,16643,666,16040,153,5,1 +changed,1,62,11977,11827,630,11391,135,2,0 +changed,1,63,10163,10111,580,9690,144,6,0 +changed,1,64,8196,8141,528,7685,129,3,0 +changed,1,65,5787,5743,506,5319,128,4,0 +changed,1,66,4568,4506,489,4170,126,5,0 +changed,1,67,3795,3744,459,3369,119,3,0 +changed,1,68,3082,3021,420,2718,111,4,0 +changed,1,69,2516,2353,397,2081,96,3,0 +changed,1,70,2202,2115,400,1880,101,4,0 +changed,1,71,1998,1923,454,1661,109,3,1 +changed,1,72,1973,1907,468,1623,112,4,0 +changed,1,73,1888,1802,473,1514,97,5,0 +changed,1,74,1849,1764,475,1450,91,4,0 +changed,1,75,1688,1617,486,1315,95,4,0 +changed,1,76,1583,1456,480,1232,93,3,1 +changed,1,77,1552,1475,473,1226,93,6,1 +changed,1,78,1433,1337,470,1126,90,4,0 +changed,1,79,1501,1402,483,1168,85,13,0 +changed,1,80,1617,1514,481,1265,93,10,0 +changed,1,81,1415,1314,490,1119,80,4,1 +changed,1,82,1528,1417,532,1162,96,9,0 +changed,1,83,1493,1388,566,1152,92,9,1 +changed,1,84,1449,1360,587,1065,81,4,0 +changed,1,85,1428,1377,587,1066,86,4,1 +changed,1,86,1298,1230,583,1003,85,6,0 +changed,1,87,1382,1300,572,990,96,5,0 +changed,1,88,1392,1308,568,1019,87,15,0 +changed,1,89,1405,1227,565,973,79,6,0 +changed,1,90,1253,1179,554,958,80,6,0 +changed,1,91,1337,1248,547,990,79,8,0 +changed,1,92,1298,1207,547,981,87,7,0 +changed,1,93,1315,1265,533,993,88,8,0 +changed,1,94,1231,1184,530,978,78,6,1 +changed,1,95,1278,1217,564,988,89,7,1 +changed,1,96,1410,1225,582,955,79,4,0 +changed,1,97,1333,1274,561,935,82,3,1 +changed,1,98,1289,1227,545,930,80,4,0 +changed,1,99,1183,1131,537,898,72,7,1 +changed,1,100,1321,1211,539,941,84,5,0 +changed,1,101,1264,1169,534,930,91,7,0 +changed,1,102,1189,1107,533,895,74,4,2 +changed,1,103,1366,1153,524,873,78,4,1 +changed,1,104,1141,1079,505,877,70,7,1 +changed,1,105,1253,1158,488,880,79,16,0 +changed,1,106,1186,1117,483,906,75,8,0 +changed,1,107,1224,1138,482,884,74,6,0 +changed,1,108,1172,1122,472,892,73,13,0 +changed,1,109,1306,1081,447,824,66,4,0 +changed,1,110,1135,1043,434,835,68,3,0 +changed,1,111,1599,1101,420,785,74,4,1 +changed,1,112,1102,1038,406,822,72,4,0 +changed,1,113,1109,1021,386,806,80,4,1 +changed,1,114,1109,1066,369,790,67,3,0 +changed,1,115,1042,953,358,769,70,4,0 +changed,1,116,1213,981,347,739,67,20,0 +changed,1,117,1070,987,342,771,65,12,0 +changed,1,118,1089,1010,333,754,72,5,0 +changed,1,119,1046,901,332,736,65,3,1 +changed,1,120,6907,1098,840,690,182,3,0 +changed,1,121,16983,16898,811,16235,183,14,1 +changed,1,122,12255,12064,772,11601,163,3,0 +changed,1,123,10080,10030,720,9546,164,3,0 +changed,1,124,7685,7642,655,7193,142,3,0 +changed,1,125,5963,5899,614,5473,169,4,1 +changed,1,126,5015,4968,581,4553,150,3,1 +changed,1,127,3812,3755,579,3414,137,4,1 +changed,1,128,3294,3252,529,2814,127,3,0 +changed,1,129,2899,2687,514,2320,128,3,0 +changed,1,130,2597,2531,514,2182,132,9,0 +changed,1,131,2372,2332,509,1941,124,11,0 +changed,1,132,2287,2211,507,1850,121,4,1 +changed,1,133,2159,2064,504,1718,132,15,0 +changed,1,134,2061,1962,497,1673,115,8,1 +changed,1,135,2084,1992,511,1687,131,6,0 +changed,1,136,2153,1963,537,1620,121,3,0 +changed,1,137,2072,1985,548,1659,124,10,0 +changed,1,138,1910,1860,552,1576,128,4,0 +changed,1,139,1975,1876,565,1568,112,3,0 +changed,1,140,1849,1784,560,1518,112,9,0 +changed,1,141,1935,1875,552,1558,122,6,0 +changed,1,142,1706,1668,557,1402,116,3,0 +changed,1,143,1940,1728,572,1422,113,5,0 +changed,1,144,1782,1681,582,1422,95,5,0 +changed,1,145,1828,1777,586,1530,117,5,0 +changed,1,146,1746,1694,588,1449,106,5,0 +changed,1,147,1701,1630,579,1351,109,4,1 +changed,1,148,1697,1591,590,1279,110,7,1 +changed,1,149,1652,1557,580,1285,101,10,1 +changed,1,150,1815,1583,571,1274,114,3,0 +changed,1,151,1747,1675,565,1414,103,4,0 +changed,1,152,1677,1590,570,1294,99,10,0 +changed,1,153,1650,1557,572,1246,106,10,0 +changed,1,154,1511,1423,561,1176,99,4,1 +changed,1,155,1506,1419,566,1160,105,7,0 +changed,1,156,1529,1467,565,1201,98,7,0 +changed,1,157,1766,1547,550,1251,106,4,0 +changed,1,158,1572,1507,554,1216,103,5,0 +changed,1,159,1561,1468,551,1195,99,9,0 +changed,1,160,1498,1401,540,1116,103,4,0 +changed,1,161,1375,1281,538,1062,98,4,0 +changed,1,162,1383,1331,539,1072,97,6,0 +changed,1,163,1481,1379,532,1096,95,4,0 +changed,1,164,1533,1305,524,1044,87,4,1 +changed,1,165,1454,1348,513,1093,98,11,0 +changed,1,166,1468,1375,492,1088,91,14,1 +changed,1,167,1292,1245,478,999,91,6,0 +changed,1,168,1340,1298,478,1070,91,4,0 +changed,1,169,1422,1354,462,1095,87,5,1 +changed,1,170,1353,1261,449,1031,88,7,1 +changed,1,171,1471,1243,447,973,101,3,0 +changed,1,172,1401,1309,446,1027,91,20,0 +changed,1,173,1264,1172,434,952,83,9,1 +changed,1,174,1319,1228,424,966,89,4,1 +changed,1,175,1372,1272,435,1005,90,7,1 +changed,1,176,1293,1218,430,963,81,8,0 +changed,1,177,1341,1148,444,931,84,3,0 +changed,1,178,1224,1132,440,903,80,6,0 +changed,1,179,1350,1221,438,950,90,4,1 +changed,1,180,6667,1237,883,853,176,3,0 +changed,1,181,16440,16341,860,15821,174,5,1 +changed,1,182,12115,12072,804,11612,155,11,0 +changed,1,183,9827,9678,742,9239,155,4,0 +changed,1,184,7948,7534,696,7075,145,3,1 +changed,1,185,5958,5918,656,5547,154,6,0 +changed,1,186,4682,4626,625,4169,146,4,0 +changed,1,187,3563,3505,584,3140,137,7,1 +changed,1,188,2891,2820,553,2451,119,4,0 +changed,1,189,2884,2713,526,2334,124,3,0 +changed,1,190,2516,2426,510,2106,138,5,1 +changed,1,191,2390,2307,501,1969,128,3,0 +changed,1,192,2162,2079,488,1780,112,3,0 +changed,1,193,2075,1973,498,1690,129,8,0 +changed,1,194,1937,1850,504,1607,100,5,0 +changed,1,195,1946,1864,496,1566,129,3,1 +changed,1,196,1927,1700,480,1444,115,10,0 +changed,1,197,1892,1823,469,1510,112,4,0 +changed,1,198,1810,1721,477,1424,116,13,0 +changed,1,199,1735,1647,469,1341,99,12,0 +changed,1,200,1771,1679,461,1340,114,18,1 +changed,1,201,1578,1527,454,1260,106,4,0 +changed,1,202,1641,1471,447,1193,104,3,0 +changed,1,203,1518,1450,440,1210,109,6,1 +changed,1,204,1472,1394,431,1172,91,4,0 +changed,1,205,1524,1423,423,1136,108,9,1 +changed,1,206,1504,1433,404,1158,101,3,0 +changed,1,207,1592,1530,401,1300,97,4,1 +changed,1,208,1583,1485,419,1216,100,12,0 +changed,1,209,1490,1340,420,1114,100,4,1 +changed,1,210,1586,1494,416,1155,102,14,0 +changed,1,211,1526,1426,406,1152,101,17,0 +changed,1,212,1384,1303,410,1069,100,5,0 +changed,1,213,1462,1359,411,1075,97,8,1 +changed,1,214,1389,1284,406,1045,87,6,0 +changed,1,215,1448,1353,401,1069,107,8,0 +changed,1,216,1537,1314,389,1058,93,3,1 +changed,1,217,1411,1332,379,1036,88,11,0 +changed,1,218,1315,1207,377,976,91,19,0 +changed,1,219,1302,1197,374,974,88,8,0 +changed,1,220,1316,1209,374,976,105,7,2 +changed,1,221,1245,1188,366,965,86,4,0 +changed,1,222,1389,1333,363,1061,88,7,0 +changed,1,223,1491,1261,357,983,98,3,0 +changed,1,224,1283,1223,355,986,81,2,1 +changed,1,225,1305,1259,357,1030,80,3,1 +changed,1,226,1289,1191,363,947,97,4,1 +changed,1,227,1379,1278,367,952,85,10,0 +changed,1,228,1316,1212,355,940,87,9,0 +changed,1,229,1270,1185,350,937,77,7,1 +changed,1,230,1482,1213,345,903,99,4,1 +changed,1,231,1355,1260,345,947,89,15,0 +changed,1,232,1312,1219,340,941,89,3,0 +changed,1,233,1193,1116,339,880,83,4,1 +changed,1,234,1174,1105,331,889,72,4,0 +changed,1,235,1206,1110,331,895,91,3,0 +changed,1,236,1211,1159,325,931,83,4,0 +changed,1,237,1281,1060,314,839,81,3,0 +changed,1,238,1216,1140,294,892,77,14,0 +changed,1,239,1183,1039,290,822,66,2,1 +changed,2,0,6159,533,508,0,139,173,0 +changed,2,1,15469,15419,487,14876,98,4,0 +changed,2,2,11575,11532,455,11139,105,5,0 +changed,2,3,9868,9821,412,9463,108,4,0 +changed,2,4,7351,7311,359,6982,97,11,0 +changed,2,5,5392,5305,314,5007,94,4,0 +changed,2,6,4156,4109,274,3780,93,4,1 +changed,2,7,3093,3032,248,2770,79,7,0 +changed,2,8,2729,2664,242,2377,83,7,1 +changed,2,9,2059,1993,256,1712,65,4,0 +changed,2,10,1716,1611,271,1424,74,4,0 +changed,2,11,1694,1617,361,1380,66,7,0 +changed,2,12,1524,1474,372,1284,63,9,0 +changed,2,13,1548,1453,383,1172,81,7,1 +changed,2,14,1371,1270,391,1049,68,3,1 +changed,2,15,1203,1141,390,962,66,7,0 +changed,2,16,1215,1121,390,928,65,3,0 +changed,2,17,1238,1130,393,910,75,9,0 +changed,2,18,1269,1200,413,960,63,4,0 +changed,2,19,1174,1081,419,859,60,4,0 +changed,2,20,1203,1121,429,832,65,12,0 +changed,2,21,1163,1053,425,851,60,4,0 +changed,2,22,1126,1033,432,848,62,5,0 +changed,2,23,1097,1012,451,804,57,6,0 +changed,2,24,1074,1022,448,825,67,5,0 +changed,2,25,1102,989,449,778,60,8,1 +changed,2,26,1099,1049,443,824,60,4,0 +changed,2,27,1043,958,433,770,57,4,1 +changed,2,28,1117,1034,434,792,54,13,1 +changed,2,29,1079,973,424,750,55,20,2 +changed,2,30,1095,927,416,697,58,4,1 +changed,2,31,1032,923,409,686,56,10,2 +changed,2,32,995,904,401,707,54,4,0 +changed,2,33,1030,949,392,684,55,5,1 +changed,2,34,1041,931,385,694,53,7,1 +changed,2,35,955,897,374,684,54,4,0 +changed,2,36,1034,961,374,698,63,9,0 +changed,2,37,944,896,367,702,50,3,0 +changed,2,38,978,870,362,634,51,5,2 +changed,2,39,856,808,352,622,46,7,0 +changed,2,40,950,899,342,656,55,5,0 +changed,2,41,976,899,309,706,49,7,0 +changed,2,42,915,829,283,634,54,9,0 +changed,2,43,880,835,274,656,48,3,0 +changed,2,44,909,764,267,572,48,4,1 +changed,2,45,900,857,267,636,48,4,1 +changed,2,46,829,779,259,582,48,3,0 +changed,2,47,780,739,251,576,46,4,0 +changed,2,48,853,777,240,564,43,4,0 +changed,2,49,857,779,235,572,44,6,1 +changed,2,50,873,699,237,549,45,4,0 +changed,2,51,834,760,245,598,52,4,0 +changed,2,52,922,822,239,584,52,4,1 +changed,2,53,871,779,229,590,55,4,0 +changed,2,54,848,755,221,569,42,4,0 +changed,2,55,781,714,213,556,45,4,1 +changed,2,56,848,771,203,553,41,6,0 +changed,2,57,903,732,200,556,43,4,1 +changed,2,58,857,773,193,562,42,8,0 +changed,2,59,884,727,190,547,44,3,0 +changed,2,60,6234,817,696,473,169,3,1 +changed,2,61,16224,16124,666,15642,150,4,0 +changed,2,62,11710,11664,630,11276,136,3,0 +changed,2,63,9978,9848,580,9424,146,4,1 +changed,2,64,8177,8112,528,7735,135,3,1 +changed,2,65,5647,5574,506,5236,133,4,0 +changed,2,66,4552,4472,489,4161,116,7,0 +changed,2,67,3769,3699,459,3373,121,4,0 +changed,2,68,3011,2930,420,2665,111,4,0 +changed,2,69,2555,2456,397,2145,99,5,2 +changed,2,70,2290,2090,400,1826,95,4,1 +changed,2,71,2207,2108,454,1773,112,8,0 +changed,2,72,1937,1838,468,1599,105,6,0 +changed,2,73,1850,1749,473,1527,95,5,0 +changed,2,74,1823,1723,475,1433,91,16,1 +changed,2,75,1656,1552,486,1321,98,9,1 +changed,2,76,1559,1471,480,1254,86,4,0 +changed,2,77,1591,1398,473,1173,97,4,0 +changed,2,78,1459,1366,470,1109,97,4,0 +changed,2,79,1486,1388,483,1176,81,5,1 +changed,2,80,1551,1454,481,1168,93,14,0 +changed,2,81,1513,1418,490,1182,92,7,1 +changed,2,82,1552,1457,532,1175,83,5,1 +changed,2,83,1577,1470,566,1170,91,5,1 +changed,2,84,1570,1520,587,1267,78,3,0 +changed,2,85,1489,1393,587,1087,86,9,0 +changed,2,86,1516,1431,583,1080,84,4,1 +changed,2,87,2716,2648,572,1072,89,6,1 +changed,2,88,1506,1444,568,1093,87,13,1 +changed,2,89,1414,1245,565,1027,87,5,0 +changed,2,90,1351,1247,554,1020,88,4,1 +changed,2,91,1347,1244,547,1033,77,4,1 +changed,2,92,1273,1225,547,1030,80,4,0 +changed,2,93,1330,1246,533,1033,76,15,0 +changed,2,94,1265,1170,530,970,76,4,1 +changed,2,95,1339,1239,564,1016,75,5,0 +changed,2,96,1429,1202,582,989,86,4,1 +changed,2,97,1327,1271,561,1034,83,5,0 +changed,2,98,1268,1199,545,957,77,4,1 +changed,2,99,1308,1253,537,938,81,5,0 +changed,2,100,1304,1193,539,934,78,5,0 +changed,2,101,1241,1160,534,941,82,6,0 +changed,2,102,1201,1139,533,922,74,5,0 +changed,2,103,1359,1133,524,876,72,5,0 +changed,2,104,1289,1208,505,935,86,9,0 +changed,2,105,1277,1191,488,890,83,6,0 +changed,2,106,1185,1095,483,874,76,5,0 +changed,2,107,1226,1119,482,856,71,5,1 +changed,2,108,1161,1112,472,924,72,9,0 +changed,2,109,1311,1092,447,881,69,4,0 +changed,2,110,1252,1159,434,853,82,9,1 +changed,2,111,1582,1106,420,828,72,6,0 +changed,2,112,1237,1177,406,911,69,9,1 +changed,2,113,1225,1112,386,835,79,4,1 +changed,2,114,1103,1027,369,802,64,4,1 +changed,2,115,1131,1070,358,796,75,4,0 +changed,2,116,1163,933,347,751,69,4,0 +changed,2,117,1252,1142,342,857,77,9,0 +changed,2,118,1058,952,333,747,70,11,1 +changed,2,119,1132,974,332,751,69,4,1 +changed,2,120,6553,988,840,659,185,4,0 +changed,2,121,16807,16741,811,16123,185,5,0 +changed,2,122,12561,12394,772,11861,162,7,0 +changed,2,123,9958,9919,720,9498,162,3,0 +changed,2,124,7550,7500,655,7080,156,9,0 +changed,2,125,5920,5842,614,5393,154,5,0 +changed,2,126,5037,4958,581,4533,150,4,0 +changed,2,127,3834,3788,579,3382,127,3,0 +changed,2,128,3193,3136,529,2752,141,7,0 +changed,2,129,2746,2582,514,2311,128,4,0 +changed,2,130,2570,2493,514,2170,133,3,0 +changed,2,131,2309,2220,509,1903,122,3,1 +changed,2,132,2290,2212,507,1917,118,6,1 +changed,2,133,2002,1932,504,1665,115,6,0 +changed,2,134,1979,1906,497,1646,105,6,0 +changed,2,135,2060,1958,511,1695,123,10,0 +changed,2,136,2119,1904,537,1604,137,3,0 +changed,2,137,2073,1983,548,1678,121,5,0 +changed,2,138,1992,1908,552,1553,112,4,1 +changed,2,139,1942,1855,565,1584,105,8,1 +changed,2,140,1932,1841,560,1496,125,5,0 +changed,2,141,1848,1769,552,1481,110,7,1 +changed,2,142,1839,1760,557,1481,107,7,0 +changed,2,143,1907,1650,572,1417,106,4,0 +changed,2,144,1832,1750,582,1497,95,10,1 +changed,2,145,1739,1645,586,1371,117,4,0 +changed,2,146,1669,1619,588,1317,107,5,0 +changed,2,147,1652,1573,579,1282,104,4,0 +changed,2,148,1637,1571,590,1275,120,4,0 +changed,2,149,1715,1482,580,1249,96,4,1 +changed,2,150,1622,1523,571,1260,106,8,0 +changed,2,151,1646,1577,565,1289,109,7,0 +changed,2,152,1647,1574,570,1273,97,4,0 +changed,2,153,1690,1605,572,1237,115,8,1 +changed,2,154,1565,1485,561,1180,93,4,0 +changed,2,155,1649,1554,566,1230,106,8,1 +changed,2,156,1647,1446,565,1194,102,5,0 +changed,2,157,1523,1444,550,1168,99,14,0 +changed,2,158,1540,1449,554,1160,95,12,1 +changed,2,159,1571,1481,551,1146,93,10,0 +changed,2,160,1505,1399,540,1107,98,4,1 +changed,2,161,1516,1433,538,1079,99,4,1 +changed,2,162,1485,1277,539,1052,90,5,0 +changed,2,163,1434,1374,532,1090,90,6,0 +changed,2,164,1409,1353,524,1090,90,3,0 +changed,2,165,1521,1421,513,1053,101,5,0 +changed,2,166,1479,1392,492,1108,91,4,0 +changed,2,167,1384,1321,478,1030,88,11,0 +changed,2,168,1408,1308,478,1036,95,8,1 +changed,2,169,1392,1245,462,983,78,10,0 +changed,2,170,1428,1381,449,1097,95,11,0 +changed,2,171,1307,1210,447,987,90,7,1 +changed,2,172,1313,1221,446,980,89,9,1 +changed,2,173,1295,1202,434,958,89,6,2 +changed,2,174,1211,1174,424,951,79,4,0 +changed,2,175,1395,1207,435,964,82,7,2 +changed,2,176,1481,1392,430,1065,88,4,0 +changed,2,177,1307,1229,444,953,82,5,0 +changed,2,178,1277,1187,440,906,84,7,1 +changed,2,179,1291,1188,438,956,75,4,0 +changed,2,180,6374,1295,883,864,182,6,0 +changed,2,181,16478,16393,860,15774,177,4,0 +changed,2,182,12340,12135,804,11621,162,3,1 +changed,2,183,9694,9643,742,9189,160,7,0 +changed,2,184,7977,7497,696,7019,154,4,0 +changed,2,185,5981,5916,656,5496,152,6,0 +changed,2,186,4534,4484,625,4124,137,9,1 +changed,2,187,3485,3429,584,3083,135,4,1 +changed,2,188,2873,2762,553,2444,121,3,0 +changed,2,189,2702,2612,526,2278,124,5,0 +changed,2,190,2479,2384,510,2074,135,8,0 +changed,2,191,2335,2235,501,1960,127,4,1 +changed,2,192,2140,2057,488,1746,113,10,0 +changed,2,193,2007,1954,498,1700,117,3,1 +changed,2,194,1915,1856,504,1585,107,6,0 +changed,2,195,2024,1821,496,1554,117,3,0 +changed,2,196,1841,1748,480,1470,115,3,1 +changed,2,197,1768,1725,469,1462,107,6,0 +changed,2,198,1860,1763,477,1409,121,7,0 +changed,2,199,1737,1644,469,1365,109,5,1 +changed,2,200,1633,1563,461,1300,106,3,0 +changed,2,201,1762,1562,454,1183,104,3,0 +changed,2,202,1596,1493,447,1254,107,4,0 +changed,2,203,1487,1423,440,1176,100,4,0 +changed,2,204,1578,1486,431,1200,95,12,0 +changed,2,205,1581,1466,423,1163,105,4,2 +changed,2,206,1541,1434,404,1179,103,6,1 +changed,2,207,1587,1494,401,1156,94,9,0 +changed,2,208,1629,1454,419,1149,100,6,0 +changed,2,209,1463,1374,420,1133,90,6,1 +changed,2,210,1514,1447,416,1152,100,8,1 +changed,2,211,1492,1407,406,1149,100,8,0 +changed,2,212,1461,1370,410,1085,98,9,0 +changed,2,213,1416,1317,411,1071,97,4,0 +changed,2,214,1424,1339,406,1096,92,3,0 +changed,2,215,1485,1278,401,1053,97,3,0 +changed,2,216,1520,1427,389,1053,105,7,1 +changed,2,217,1312,1236,379,984,86,4,1 +changed,2,218,1337,1274,377,993,99,7,1 +changed,2,219,1281,1218,374,965,80,9,0 +changed,2,220,1443,1396,374,1086,90,4,0 +changed,2,221,1258,1170,366,951,89,15,1 +changed,2,222,1402,1186,363,942,84,4,1 +changed,2,223,1321,1221,357,986,99,4,0 +changed,2,224,1234,1198,355,970,80,8,1 +changed,2,225,1337,1246,357,978,86,9,0 +changed,2,226,1344,1258,363,938,93,8,1 +changed,2,227,1251,1162,367,949,94,5,0 +changed,2,228,1433,1204,355,901,82,3,1 +changed,2,229,1276,1185,350,973,87,4,0 +changed,2,230,1254,1158,345,915,86,6,1 +changed,2,231,1193,1144,345,945,82,4,0 +changed,2,232,1310,1221,340,937,85,16,0 +changed,2,233,1240,1140,339,919,86,12,1 +changed,2,234,1202,1125,331,890,75,4,0 +changed,2,235,1309,1081,331,856,81,3,0 +changed,2,236,1233,1144,325,904,88,4,0 +changed,2,237,1197,1101,314,880,81,10,0 +changed,2,238,1208,1110,294,871,81,10,1 +changed,2,239,1203,1051,290,828,73,3,1 +changed,3,0,6277,629,508,1,137,167,0 +changed,3,1,15464,15419,487,14909,100,3,0 +changed,3,2,11597,11548,455,11126,107,3,0 +changed,3,3,9863,9819,412,9432,107,7,0 +changed,3,4,7441,7384,359,7003,92,5,0 +changed,3,5,5298,5202,314,4938,98,4,0 +changed,3,6,4272,4192,274,3907,87,10,0 +changed,3,7,3003,2944,248,2629,88,8,0 +changed,3,8,2606,2544,242,2344,72,6,0 +changed,3,9,1952,1897,256,1671,66,17,0 +changed,3,10,1788,1715,271,1471,79,4,0 +changed,3,11,1669,1594,361,1381,75,12,1 +changed,3,12,1504,1460,372,1228,64,4,0 +changed,3,13,1376,1310,383,1096,72,7,0 +changed,3,14,1340,1285,391,1109,64,4,0 +changed,3,15,1249,1181,390,975,66,9,0 +changed,3,16,1267,1185,390,916,73,3,0 +changed,3,17,1186,1079,393,860,68,4,1 +changed,3,18,1163,1088,413,893,67,16,0 +changed,3,19,1223,1128,419,864,64,5,1 +changed,3,20,1104,1011,429,813,62,14,0 +changed,3,21,1138,1044,425,837,66,7,0 +changed,3,22,1131,1045,432,872,62,5,1 +changed,3,23,1131,1064,451,820,60,6,0 +changed,3,24,1165,1071,448,866,66,6,1 +changed,3,25,995,944,449,768,59,7,0 +changed,3,26,1097,996,443,786,59,4,0 +changed,3,27,1016,953,433,752,59,13,0 +changed,3,28,1035,944,434,725,58,13,0 +changed,3,29,1065,960,424,770,52,5,1 +changed,3,30,1031,904,416,708,59,14,0 +changed,3,31,1021,922,409,729,58,6,0 +changed,3,32,979,901,401,686,57,5,0 +changed,3,33,914,860,392,711,55,4,0 +changed,3,34,931,866,385,678,50,7,0 +changed,3,35,950,871,374,683,54,16,0 +changed,3,36,1021,911,374,686,52,6,1 +changed,3,37,918,872,367,684,51,6,0 +changed,3,38,1034,980,362,698,50,5,0 +changed,3,39,898,841,352,673,49,5,0 +changed,3,40,934,830,342,634,54,10,1 +changed,3,41,967,877,309,685,53,16,0 +changed,3,42,986,828,283,604,47,5,0 +changed,3,43,991,893,274,630,59,4,1 +changed,3,44,859,808,267,575,49,4,0 +changed,3,45,894,826,267,630,56,5,0 +changed,3,46,860,783,259,582,49,4,0 +changed,3,47,925,824,251,610,52,6,0 +changed,3,48,855,804,240,598,54,5,0 +changed,3,49,880,743,235,555,47,4,1 +changed,3,50,840,788,237,591,50,7,0 +changed,3,51,904,820,245,592,47,9,9 +changed,3,52,868,773,239,613,45,3,0 +changed,3,53,843,793,229,643,50,5,1 +changed,3,54,887,785,221,563,45,5,0 +changed,3,55,838,735,213,572,46,4,0 +changed,3,56,944,736,203,541,44,4,1 +changed,3,57,859,763,200,595,42,9,0 +changed,3,58,801,739,193,544,40,4,0 +changed,3,59,853,707,190,529,45,9,0 +changed,3,60,6364,780,696,474,174,5,0 +changed,3,61,16492,16447,666,15927,148,4,0 +changed,3,62,11915,11752,630,11349,144,3,0 +changed,3,63,10112,10061,580,9570,149,7,0 +changed,3,64,8160,8102,528,7693,135,7,0 +changed,3,65,5560,5499,506,5157,130,3,1 +changed,3,66,4551,4498,489,4137,114,6,1 +changed,3,67,3803,3727,459,3341,120,4,1 +changed,3,68,3128,2970,420,2661,104,5,0 +changed,3,69,2526,2479,397,2108,104,7,0 +changed,3,70,2165,2114,400,1810,110,4,0 +changed,3,71,2125,2041,454,1709,108,4,0 +changed,3,72,1933,1879,468,1621,109,7,0 +changed,3,73,1865,1773,473,1534,101,4,1 +changed,3,74,1863,1778,475,1451,89,5,0 +changed,3,75,1758,1626,486,1316,97,3,0 +changed,3,76,1545,1501,480,1262,93,5,0 +changed,3,77,1598,1515,473,1208,95,3,0 +changed,3,78,1510,1438,470,1149,95,5,0 +changed,3,79,1618,1554,483,1244,88,10,0 +changed,3,80,1572,1473,481,1169,97,4,0 +changed,3,81,1489,1333,490,1108,90,5,0 +changed,3,82,1489,1409,532,1167,90,5,0 +changed,3,83,1470,1422,566,1181,84,6,0 +changed,3,84,1507,1417,587,1118,81,5,0 +changed,3,85,1362,1272,587,1045,84,5,0 +changed,3,86,1323,1253,583,1030,83,5,0 +changed,3,87,1324,1267,572,1027,81,9,1 +changed,3,88,1351,1174,568,975,80,4,0 +changed,3,89,1235,1180,565,956,74,4,1 +changed,3,90,1440,1341,554,1019,81,12,0 +changed,3,91,1401,1309,547,1001,75,7,0 +changed,3,92,1330,1243,547,969,83,8,1 +changed,3,93,1354,1276,533,1010,76,8,0 +changed,3,94,1342,1260,530,969,74,9,0 +changed,3,95,1399,1211,564,970,77,4,0 +changed,3,96,1250,1207,582,1004,75,3,0 +changed,3,97,1316,1267,561,961,85,15,0 +changed,3,98,1293,1195,545,952,83,8,0 +changed,3,99,1231,1187,537,953,72,7,0 +changed,3,100,1251,1179,539,922,80,8,0 +changed,3,101,1302,1255,534,958,79,7,1 +changed,3,102,1343,1142,533,884,71,4,1 +changed,3,103,1180,1115,524,893,72,5,0 +changed,3,104,1227,1136,505,901,65,9,0 +changed,3,105,1208,1102,488,887,76,6,1 +changed,3,106,1165,1102,483,899,70,9,0 +changed,3,107,1123,1047,482,846,70,4,2 +changed,3,108,1207,1153,472,912,73,8,0 +changed,3,109,1390,1114,447,857,65,9,0 +changed,3,110,1163,1083,434,864,71,6,1 +changed,3,111,1516,1028,420,783,72,4,0 +changed,3,112,1081,1014,406,813,66,4,0 +changed,3,113,1141,1043,386,809,65,8,1 +changed,3,114,1109,1023,369,789,60,12,0 +changed,3,115,1125,1080,358,810,67,6,0 +changed,3,116,1202,991,347,733,73,5,1 +changed,3,117,1084,1001,342,770,68,13,1 +changed,3,118,1078,989,333,730,65,17,1 +changed,3,119,1065,942,332,735,71,3,1 +changed,3,120,6398,1035,840,678,195,4,0 +changed,3,121,16761,16683,811,15980,188,8,0 +changed,3,122,12132,11968,772,11514,158,3,1 +changed,3,123,10020,9967,720,9490,162,4,0 +changed,3,124,7479,7434,655,7021,150,6,0 +changed,3,125,5990,5931,614,5455,151,4,0 +changed,3,126,4931,4827,581,4412,151,7,1 +changed,3,127,3762,3710,579,3391,128,7,0 +changed,3,128,3209,3127,529,2768,136,6,1 +changed,3,129,2707,2545,514,2285,119,4,0 +changed,3,130,2521,2479,514,2179,130,3,1 +changed,3,131,2310,2270,509,1970,126,4,0 +changed,3,132,2236,2193,507,1875,121,8,0 +changed,3,133,2018,1969,504,1710,115,6,0 +changed,3,134,2211,2156,497,1824,111,9,0 +changed,3,135,2198,1980,511,1637,127,3,0 +changed,3,136,1970,1887,537,1619,135,4,1 +changed,3,137,2050,1978,548,1632,118,15,0 +changed,3,138,1878,1789,552,1524,125,13,0 +changed,3,139,1927,1882,565,1604,122,6,0 +changed,3,140,1913,1848,560,1503,117,7,1 +changed,3,141,1964,1756,552,1499,105,4,1 +changed,3,142,1794,1750,557,1499,115,8,0 +changed,3,143,1840,1767,572,1445,111,16,1 +changed,3,144,1732,1641,582,1407,99,4,0 +changed,3,145,1717,1618,586,1346,112,3,1 +changed,3,146,1649,1565,588,1288,101,6,0 +changed,3,147,1620,1542,579,1256,101,5,0 +changed,3,148,1811,1594,590,1328,105,5,1 +changed,3,149,1707,1642,580,1331,86,16,1 +changed,3,150,1614,1548,571,1211,117,3,1 +changed,3,151,1679,1575,565,1271,115,8,0 +changed,3,152,1614,1570,570,1257,98,7,0 +changed,3,153,1692,1598,572,1258,101,8,0 +changed,3,154,1585,1426,561,1138,93,4,0 +changed,3,155,1590,1507,566,1176,104,3,0 +changed,3,156,1531,1444,565,1174,107,3,1 +changed,3,157,1446,1388,550,1166,93,6,0 +changed,3,158,1464,1406,554,1109,96,5,1 +changed,3,159,1436,1355,551,1119,99,4,0 +changed,3,160,1442,1356,540,1096,93,4,1 +changed,3,161,1522,1304,538,1037,97,3,0 +changed,3,162,1421,1329,539,1054,92,4,1 +changed,3,163,1436,1389,532,1155,95,7,0 +changed,3,164,1468,1391,524,1139,93,14,0 +changed,3,165,1401,1318,513,1069,101,15,0 +changed,3,166,1440,1352,492,1042,91,7,1 +changed,3,167,1373,1230,478,988,89,5,0 +changed,3,168,1317,1252,478,1022,86,4,0 +changed,3,169,1416,1345,462,1034,87,8,1 +changed,3,170,1366,1262,449,1007,87,12,1 +changed,3,171,1341,1249,447,1027,90,5,0 +changed,3,172,1330,1286,446,1012,90,4,0 +changed,3,173,1321,1239,434,955,81,11,1 +changed,3,174,1382,1214,424,944,75,3,1 +changed,3,175,1430,1364,435,1088,91,7,1 +changed,3,176,1272,1211,430,968,88,4,0 +changed,3,177,1323,1234,444,940,83,15,1 +changed,3,178,1302,1205,440,942,76,10,0 +changed,3,179,1212,1117,438,887,71,3,0 +changed,3,180,6801,1236,883,846,181,4,0 +changed,3,181,16195,16095,860,15467,178,8,1 +changed,3,182,11951,11919,804,11476,156,3,0 +changed,3,183,9631,9571,742,9102,164,6,0 +changed,3,184,7733,7286,696,6925,151,4,0 +changed,3,185,5937,5899,656,5452,155,4,1 +changed,3,186,4742,4575,625,4186,141,4,0 +changed,3,187,3590,3519,584,3105,129,3,1 +changed,3,188,2920,2818,553,2478,134,4,0 +changed,3,189,2732,2650,526,2318,118,4,0 +changed,3,190,2417,2353,510,2077,132,3,0 +changed,3,191,2344,2244,501,1962,132,11,2 +changed,3,192,2143,2051,488,1744,114,4,0 +changed,3,193,2122,1888,498,1636,124,3,1 +changed,3,194,2034,1949,504,1632,105,8,1 +changed,3,195,1836,1790,496,1535,110,4,1 +changed,3,196,1884,1787,480,1436,118,8,1 +changed,3,197,1832,1765,469,1430,116,11,1 +changed,3,198,1796,1695,477,1444,109,4,0 +changed,3,199,1773,1678,469,1353,110,3,0 +changed,3,200,1750,1546,461,1281,105,4,0 +changed,3,201,1675,1576,454,1260,102,13,1 +changed,3,202,1553,1453,447,1214,101,11,0 +changed,3,203,1639,1546,440,1246,106,4,2 +changed,3,204,1635,1562,431,1232,94,13,0 +changed,3,205,1475,1382,423,1132,106,9,0 +changed,3,206,1584,1479,404,1187,95,5,1 +changed,3,207,1543,1351,401,1121,101,4,0 +changed,3,208,1541,1495,419,1239,105,7,0 +changed,3,209,1472,1421,420,1122,92,14,0 +changed,3,210,1532,1419,416,1148,100,9,1 +changed,3,211,1514,1439,406,1170,94,6,0 +changed,3,212,1431,1380,410,1152,99,4,0 +changed,3,213,1475,1250,411,1029,95,3,1 +changed,3,214,1399,1301,406,1070,88,16,1 +changed,3,215,1498,1380,401,1086,103,9,0 +changed,3,216,1413,1323,389,1043,92,7,0 +changed,3,217,1333,1265,379,997,89,4,0 +changed,3,218,1266,1209,377,980,93,12,0 +changed,3,219,1477,1265,374,987,84,3,0 +changed,3,220,1338,1287,374,1017,94,6,0 +changed,3,221,1309,1210,366,948,86,4,1 +changed,3,222,1366,1271,363,967,93,8,1 +changed,3,223,1254,1170,357,954,87,6,0 +changed,3,224,1339,1252,355,1002,86,7,0 +changed,3,225,1334,1175,357,963,82,4,1 +changed,3,226,1331,1239,363,971,93,4,0 +changed,3,227,1286,1185,367,963,81,7,0 +changed,3,228,1292,1243,355,997,77,5,1 +changed,3,229,1168,1077,350,884,75,8,1 +changed,3,230,1226,1133,345,926,82,9,1 +changed,3,231,1202,1104,345,898,81,3,2 +changed,3,232,1292,1075,340,884,78,4,0 +changed,3,233,1226,1124,339,904,84,12,1 +changed,3,234,1246,1156,331,876,76,7,1 +changed,3,235,1249,1169,331,908,84,5,0 +changed,3,236,1207,1101,325,888,79,7,0 +changed,3,237,1162,1071,314,856,81,8,0 +changed,3,238,1409,1151,294,871,71,4,0 +changed,3,239,1263,1153,290,908,70,5,0 diff --git a/Tools/Benchmarks/FlippedSpritesResults/summary.json b/Tools/Benchmarks/FlippedSpritesResults/summary.json new file mode 100644 index 0000000000..327eda7e2e --- /dev/null +++ b/Tools/Benchmarks/FlippedSpritesResults/summary.json @@ -0,0 +1,212 @@ +[ + { + "size": 12, + "unique": 1, + "baseline": { + "warm_median_ms": 22.355, + "pair_medians_ms": [ + 22.467, + 22.258, + 22.178 + ], + "cold_median_ms": 0.272, + "cold_ms": [ + 0.278, + 0.271, + 0.272 + ], + "pixels_hash": "12316631879379964747" + }, + "changed": { + "warm_median_ms": 15.843, + "pair_medians_ms": [ + 15.803, + 15.837, + 16.055 + ], + "cold_median_ms": 0.222, + "cold_ms": [ + 0.222, + 0.228, + 0.217 + ], + "pixels_hash": "12316631879379964747" + }, + "reduction_pct": 29.129948557369723 + }, + { + "size": 24, + "unique": 8, + "baseline": { + "warm_median_ms": 90.951, + "pair_medians_ms": [ + 90.741, + 90.858, + 95.023 + ], + "cold_median_ms": 0.858, + "cold_ms": [ + 0.822, + 0.858, + 0.874 + ], + "pixels_hash": "5164470368415242364" + }, + "changed": { + "warm_median_ms": 61.75, + "pair_medians_ms": [ + 61.658, + 61.964, + 61.702 + ], + "cold_median_ms": 0.674, + "cold_ms": [ + 0.697, + 0.674, + 0.666 + ], + "pixels_hash": "5164470368415242364" + }, + "reduction_pct": 32.106298996162764 + }, + { + "size": 64, + "unique": 8, + "baseline": { + "warm_median_ms": 484.79, + "pair_medians_ms": [ + 482.23, + 484.361, + 498.807 + ], + "cold_median_ms": 3.979, + "cold_ms": [ + 3.964, + 3.979, + 4.288 + ], + "pixels_hash": "7540584506724982554" + }, + "changed": { + "warm_median_ms": 331.36, + "pair_medians_ms": [ + 330.853, + 331.156, + 334.907 + ], + "cold_median_ms": 2.824, + "cold_ms": [ + 2.787, + 2.824, + 2.831 + ], + "pixels_hash": "7540584506724982554" + }, + "reduction_pct": 31.64875513108769 + }, + { + "size": 128, + "unique": 8, + "baseline": { + "warm_median_ms": 1593.83, + "pair_medians_ms": [ + 1588.78, + 1596.3, + 1601.39 + ], + "cold_median_ms": 12.586, + "cold_ms": [ + 12.586, + 12.416, + 12.634 + ], + "pixels_hash": "17320702199430413249" + }, + "changed": { + "warm_median_ms": 1028.64, + "pair_medians_ms": [ + 1019.36, + 1028.64, + 1053.47 + ], + "cold_median_ms": 7.945, + "cold_ms": [ + 8.038, + 7.945, + 7.803 + ], + "pixels_hash": "17320702199430413249" + }, + "reduction_pct": 35.46112195152556 + }, + { + "size": 24, + "unique": 512, + "baseline": { + "warm_median_ms": 88.733, + "pair_medians_ms": [ + 88.658, + 93.817, + 88.628 + ], + "cold_median_ms": 0.839, + "cold_ms": [ + 0.825, + 0.839, + 0.87 + ], + "pixels_hash": "12191707828478896987" + }, + "changed": { + "warm_median_ms": 66.646, + "pair_medians_ms": [ + 63.836, + 66.646, + 72.82 + ], + "cold_median_ms": 0.889, + "cold_ms": [ + 0.906, + 0.87, + 0.889 + ], + "pixels_hash": "12191707828478896987" + }, + "reduction_pct": 24.891528518138685 + }, + { + "size": 64, + "unique": 512, + "baseline": { + "warm_median_ms": 491.085, + "pair_medians_ms": [ + 482.648, + 496.972, + 491.085 + ], + "cold_median_ms": 4.054, + "cold_ms": [ + 3.949, + 4.072, + 4.054 + ], + "pixels_hash": "651891823647941672" + }, + "changed": { + "warm_median_ms": 346.401, + "pair_medians_ms": [ + 346.401, + 350.961, + 333.246 + ], + "cold_median_ms": 4.241, + "cold_ms": [ + 4.241, + 4.219, + 4.36 + ], + "pixels_hash": "651891823647941672" + }, + "reduction_pct": 29.462109410794458 + } +] diff --git a/Tools/Benchmarks/PerformanceStress.rte/Activities.ini b/Tools/Benchmarks/PerformanceStress.rte/Activities.ini new file mode 100644 index 0000000000..cff322fa4d --- /dev/null +++ b/Tools/Benchmarks/PerformanceStress.rte/Activities.ini @@ -0,0 +1,10 @@ +AddActivity = GAScripted + PresetName = Debris Performance Stress + Description = Fixed debris waves for local performance measurements. + TeamOfPlayer1 = 0 + MinTeamsRequired = 1 + SceneName = Grasslands + ScriptPath = PerformanceStress.rte/Stress.lua + LuaClassName = PerformanceStress + DefaultFogOfWar = 0 + DefaultDeployUnits = 0 diff --git a/Tools/Benchmarks/PerformanceStress.rte/Index.ini b/Tools/Benchmarks/PerformanceStress.rte/Index.ini new file mode 100644 index 0000000000..1ebfe00499 --- /dev/null +++ b/Tools/Benchmarks/PerformanceStress.rte/Index.ini @@ -0,0 +1,3 @@ +DataModule + ModuleName = Performance Stress + IncludeFile = PerformanceStress.rte/Activities.ini diff --git a/Tools/Benchmarks/PerformanceStress.rte/Stress.lua b/Tools/Benchmarks/PerformanceStress.rte/Stress.lua new file mode 100644 index 0000000000..be45eb81c2 --- /dev/null +++ b/Tools/Benchmarks/PerformanceStress.rte/Stress.lua @@ -0,0 +1,35 @@ +function PerformanceStress:StartActivity() + self.ActivityState = Activity.RUNNING + self.ticks = 0 + self.timer = Timer() + self.center = SceneMan:MovePointToGround(Vector(SceneMan.SceneWidth / 2, 0), 0, 3) + self.center.Y = self.center.Y - 100 + PerformanceMan.ShowPerformanceStats = true + print("PERF_START debris_waves") +end + +function PerformanceStress:UpdateActivity() + self.ticks = self.ticks + 1 + CameraMan:SetScrollTarget(self.center, 1, 0) + if self.ticks % 60 == 1 and self.ticks <= 541 then + for i = 1, 400 do + local gib = CreateMOSRotating("Gib Metal Grey Small A", "Base.rte") + gib.Pos = self.center + Vector((i * 17) % 120 - 60, (i * 23) % 80 - 40) + gib.Vel = Vector((i * 7) % 30 - 15, -((i * 11) % 20)) + gib.AngularVel = (i % 20) - 10 + gib.HFlipped = i % 2 == 0 + gib.Lifetime = 3000 + gib.GetsHitByMOs = true + MovableMan:AddParticle(gib) + end + local grenade = CreateTDExplosive("Frag Grenade", "Base.rte") + grenade.Pos = self.center + grenade:GibThis() + end + if self.ticks % 60 == 0 then + print("PERF_SAMPLE ticks=" .. self.ticks .. " real_ms=" .. self.timer.ElapsedRealTimeMS .. " particles=" .. MovableMan:GetParticleCount()) + end + if self.ticks == 600 then + print("PERF_DONE real_ms=" .. self.timer.ElapsedRealTimeMS) + end +end