From bee5465b02de7fdc8feaaed615e06fbb6e7b8c4a Mon Sep 17 00:00:00 2001 From: Alcaro Date: Sun, 25 Dec 2016 20:12:44 +0100 Subject: [PATCH] More optimizations --- arlib/global.h | 2 ++ arlib/memcmp_d.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++ patch/ips.cpp | 13 +++++++---- patch/test.cpp | 41 ++++++++++++++++---------------- 4 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 arlib/memcmp_d.cpp diff --git a/arlib/global.h b/arlib/global.h index ab4ea0b..6d540a2 100644 --- a/arlib/global.h +++ b/arlib/global.h @@ -308,6 +308,8 @@ class null_t_impl {}; #ifdef _WIN32 void* memmem(const void * haystack, size_t haystacklen, const void * needle, size_t needlelen); #endif +//Returns distance to first difference, or 'len' if that's smaller. +size_t memcmp_d(const void * a, const void * b, size_t len); //msvc: diff --git a/arlib/memcmp_d.cpp b/arlib/memcmp_d.cpp new file mode 100644 index 0000000..a70c40e --- /dev/null +++ b/arlib/memcmp_d.cpp @@ -0,0 +1,58 @@ +#include "global.h" + +size_t memcmp_d(const void * a, const void * b, size_t len) +{ + const size_t alignmul = sizeof(uintptr_t); + const size_t alignmask = alignmul-1; + + const uint8_t* ab = (uint8_t*)a; + const uint8_t* bb = (uint8_t*)b; + + if (((uintptr_t)ab^(uintptr_t)bb)&alignmask || len source, arrayview target, array& patchmem) +result create(array sourcea, arrayview target, array& patchmem) { - int truesourcelen=source.size(); + int truesourcelen=sourcea.size(); int targetlen=target.size(); - source.resize(target.size()); + sourcea.resize(target.size()); + arrayview source = sourcea; //const unsigned char * source=sourcemem.ptr(); //const unsigned char * target=targetmem.ptr(); @@ -118,7 +119,9 @@ result create(array source, arrayview target, array& patchmem) while (offset source, arrayview target, array& patchmem) //don't copy unchanged bytes at the end of a block if (offset+thislen!=targetlen) { - while (target[offset+thislen-1]==source[offset+thislen-1]) + while (thislen>1 && target[offset+thislen-1]==source[offset+thislen-1]) { thislen--; } diff --git a/patch/test.cpp b/patch/test.cpp index 69e4c08..8e6592a 100644 --- a/patch/test.cpp +++ b/patch/test.cpp @@ -131,8 +131,8 @@ static void simpletests() testcall(createtest(one0, one1, base+record+1, 21)); testcall(createtest(seq256, seq128, base+trunc, 23)); testcall(createtest(seq128, seq256, base+record+128, 153)); - testcall(createtest(empty, seq256nul4, base+record+255+4, 282)); - testcall(createtest(empty, seq256nul5, base+record+255+5, 283)); // strange how this one is bigger + testcall(createtest(empty, seq256nul4, base+record+255+6, 282)); // mistuned IPS heuristics? + testcall(createtest(empty, seq256nul5, base+record+255+6, 283)); // strange how this one is bigger testcall(createtest(empty, seq256nul6, base+record+255+6, 282)); // guess the heuristics don't like EOF testcall(createtest(empty, seq256nul7, base+record+255+record+1, 282)); testcall(createtest(empty, seq256b4, base+record+255+4, 282)); @@ -155,7 +155,7 @@ test("IPS") testips=true; testbps=false; - //simpletests(); + simpletests(); } test("BPS") @@ -163,13 +163,13 @@ test("BPS") testips=false; testbps=true; - //simpletests(); + simpletests(); } test("the big ones") { testips=true; - //testbps=true; + testbps=true; testbps=false; array smw = file::read("patch/test/smw.sfc"); @@ -187,21 +187,22 @@ test("the big ones") assert_eq(smwhack.size(), 4194304); testcall(createtest(smw, smwhack, 3302746, 2077386)); - //array sm64hack; - //r = bps::apply(sm64_bps, sm64, sm64hack); - //assert_eq(r, e_ok); - //assert_eq(sm64hack.size(), 50331648); - //testcall(createtest(sm64, sm64hack, -1, 6788133)); - //this is the only UPS test, UPS is pretty much an easter egg in Flips - //array dlhack; - //r = ups::apply(dl_ups, dl, dlhack); - //assert_eq(r, e_ok); - //assert_eq(dlhack.size(), 3145728); - //array dl2; - //r = ups::apply(dl_ups, dlhack, dl2); - //assert_eq(r, e_ok); - //assert(dl == dl2); - //testcall(createtest(dl, dlhack, 852134, 817190)); + array dlhack; + r = ups::apply(dl_ups, dl, dlhack); + assert_eq(r, e_ok); + assert_eq(dlhack.size(), 3145728); + array dl2; + r = ups::apply(dl_ups, dlhack, dl2); + assert_eq(r, e_ok); + assert(dl == dl2); + testcall(createtest(dl, dlhack, 852124, 817190)); + + array sm64hack; + r = bps::apply(sm64_bps, sm64, sm64hack); + assert_eq(r, e_ok); + assert_eq(sm64hack.size(), 50331648); + testbps=false; // too slow + testcall(createtest(sm64, sm64hack, -1, 6788133)); } }