Skip to content

Commit

Permalink
Speedup quo round up, start CL speedup integration (#8014)
Browse files Browse the repository at this point in the history
* Speedup quo round up

* Code reuse

* Missed a code re-use point

* Add future notes

* Comment cleanup

* Auto: update go.mod after push to dev/speedup_quoroundup that modified dependencies locally

* Add new fn: NewBigDecFromDecMulDec

* Auto: update go.mod after push to dev/speedup_quoroundup that modified dependencies locally

* Remove some extra ops from CL

* Further perf notes

* Make faster QuoRoundUpNextIntMut

* Auto: update go.mod after push to dev/speedup_quoroundup that modified dependencies locally

* Remove another 2 BigDec ops

* Add another dec op

* Auto: update go.mod after push to dev/speedup_quoroundup that modified dependencies locally

* Start moving some liquidity calls to Dec not BigDec

* One more BigDec x Dec op

* Auto: update go.mod after push to dev/speedup_quoroundup that modified dependencies locally

* Another liq BigDec -> Dec

* Missed one step

* Move another Liquidity BigDec -> Dec

* Minor spread reward update

* Make CalcAmount1Dec use Dec for Liquidity

* Make one more op mutative

* One more speedup

* Fix test

* Speedup SpotPrice impl

---------

Co-authored-by: github-actions <[email protected]>
  • Loading branch information
ValarDragon and github-actions authored Apr 12, 2024
1 parent def581a commit 7b599d5
Show file tree
Hide file tree
Showing 24 changed files with 357 additions and 242 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### State Compatible

* [#8006](https://github.com/osmosis-labs/osmosis/pull/8006) Speedup many BigDec operations
* [#8006](https://github.com/osmosis-labs/osmosis/pull/8006), [#8014](https://github.com/osmosis-labs/osmosis/pull/8014) Speedup many BigDec operations

## v24.0.1

Expand Down
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ require (
github.com/mattn/go-sqlite3 v1.14.17
github.com/ory/dockertest/v3 v3.10.0
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240410095049-0ddea0b91fb3
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240410095049-0ddea0b91fb3
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240410095049-0ddea0b91fb3
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240410095049-0ddea0b91fb3
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240411125512-cb0fada2dee8
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240411125512-cb0fada2dee8
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240411125512-cb0fada2dee8
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240411125512-cb0fada2dee8
github.com/osmosis-labs/sqs/sqsdomain v0.0.0-20240404053421-41aab009fb04
github.com/pkg/errors v0.9.1
github.com/rakyll/statik v0.1.7
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1517,14 +1517,14 @@ github.com/osmosis-labs/cosmos-sdk v0.47.5-v24-osmo-5 h1:fnt89Cw+55vbnIEGkpCmj0c
github.com/osmosis-labs/cosmos-sdk v0.47.5-v24-osmo-5/go.mod h1:eSRUVYwL3eG1jnh01CnBbHiqOM3xJO49p5rTOrSFX1k=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3 h1:YlmchqTmlwdWSmrRmXKR+PcU96ntOd8u10vTaTZdcNY=
github.com/osmosis-labs/go-mutesting v0.0.0-20221208041716-b43bcd97b3b3/go.mod h1:lV6KnqXYD/ayTe7310MHtM3I2q8Z6bBfMAi+bhwPYtI=
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240410095049-0ddea0b91fb3 h1:2FRCIC8gXSACn9SMmZivBXYdND/O/xrYK9rRzdY/fSY=
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240410095049-0ddea0b91fb3/go.mod h1:I1Nw0VK1JOaZH5f0AFl4iFB2Qp2ckbH9a3Z4UZLpDbs=
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240410095049-0ddea0b91fb3 h1:dJFXQbBbMZ9UDtIMseoGlBg4fe5rSui7x3x9baAGw9w=
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240410095049-0ddea0b91fb3/go.mod h1:fo3rKZIybC/tRMX09a0W/1UBl9meK1+T4PmWs1wErHI=
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240410095049-0ddea0b91fb3 h1:UGxPvBFipIM8q3SJUYRjSP0+D/3Y8BkZGLvO+ov/fYs=
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240410095049-0ddea0b91fb3/go.mod h1:N2+CB3wWEN/HmtWNK9DjAN1WGLgqeRiGjs+ZhK3RXdQ=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240410095049-0ddea0b91fb3 h1:QHtWt4M49bYH64Vy0DetURTtLGUIGWTpLOBIH9q/bhQ=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240410095049-0ddea0b91fb3/go.mod h1:C4/AaeluMrYxFehK61WGXVG7DvofFUyit7Xb0QKyQPA=
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240411125512-cb0fada2dee8 h1:p1jOOamB3IHz5qXeN50KJLEQmNx3PSz5wunNtUrSb4g=
github.com/osmosis-labs/osmosis/osmomath v0.0.12-0.20240411125512-cb0fada2dee8/go.mod h1:OQj1UyxCyuunzCPuYtbRGTvaL62OIznjQpXqdFDINbs=
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240411125512-cb0fada2dee8 h1:3BlWDp7ivc+gyjdIPxkcvcDBsATq8s+ZEUD1AxFuDzo=
github.com/osmosis-labs/osmosis/osmoutils v0.0.12-0.20240411125512-cb0fada2dee8/go.mod h1:n41vW6Nr5BmO7jCrdEONyOrJ3PACRcOt/KvhVTrEfjo=
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240411125512-cb0fada2dee8 h1:/q88xaj3yRcGpFBHnsw/FetvA3f6qa8sKSPx7L12uKw=
github.com/osmosis-labs/osmosis/x/epochs v0.0.8-0.20240411125512-cb0fada2dee8/go.mod h1:9eNG5sUawozrcuYUGhSQlsynneDXXfg7yzy7FnGa1sY=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240411125512-cb0fada2dee8 h1:m3zpevamz76sscGFDpc4LzMGE18GCAm0oAZyYtcxok8=
github.com/osmosis-labs/osmosis/x/ibc-hooks v0.0.14-0.20240411125512-cb0fada2dee8/go.mod h1:P6eRZizImh4d4nAW9iHYWFcXUJ+SQlRYqXXktlu9tuo=
github.com/osmosis-labs/sqs/sqsdomain v0.0.0-20240404053421-41aab009fb04 h1:mvkk1A/jIe+lsFFpRNfyd9UfvhagATdpnjy8K7kANeo=
github.com/osmosis-labs/sqs/sqsdomain v0.0.0-20240404053421-41aab009fb04/go.mod h1:mYYf7pYb7sGJ9zYIOw2aYlIl5cgKT0K93rZx4LvDAuA=
github.com/osmosis-labs/wasmd v0.45.0-osmo h1:NIp7pvJV5HuBN1HwPgEmXKQM2TjVIVdJErIHnB9IMO8=
Expand Down
155 changes: 81 additions & 74 deletions osmomath/decimal.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ var (
squaredPrecisionReuse = new(big.Int).Mul(defaultBigDecPrecisionReuse, defaultBigDecPrecisionReuse)
bigDecDecPrecisionFactorDiff = new(big.Int).Exp(big.NewInt(10), big.NewInt(BigDecPrecision-DecPrecision), nil)

tenTimesPrecision = new(big.Int).Exp(big.NewInt(10), big.NewInt(BigDecPrecision+1), nil)
fivePrecision = new(big.Int).Quo(defaultBigDecPrecisionReuse, big.NewInt(2))
fivePrecisionSDKDec = new(big.Int).Quo(precisionReuseSDKDec, big.NewInt(2))

precisionMultipliers []*big.Int
zeroInt = big.NewInt(0)
oneInt = big.NewInt(1)
fiveInt = big.NewInt(5)
tenInt = big.NewInt(10)

// log_2(e)
Expand Down Expand Up @@ -172,6 +174,11 @@ func NewBigDecFromIntWithPrec(i BigInt, prec int64) BigDec {
}
}

func NewBigDecFromDecMulDec(a, b Dec) BigDec {
newBi := new(big.Int).Mul(a.BigIntMut(), b.BigIntMut())
return BigDec{newBi}
}

// create a decimal from an input decimal string.
// valid must come in the form:
//
Expand Down Expand Up @@ -294,9 +301,7 @@ func (d BigDec) Add(d2 BigDec) BigDec {
func (d BigDec) AddMut(d2 BigDec) BigDec {
d.i.Add(d.i, d2.i)

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)

return d
}
Expand All @@ -310,10 +315,7 @@ func (d BigDec) Sub(d2 BigDec) BigDec {

func (d BigDec) SubMut(d2 BigDec) BigDec {
res := d.i.Sub(d.i, d2.i)

if res.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(res)
return BigDec{res}
}

Expand Down Expand Up @@ -344,9 +346,7 @@ func (d BigDec) MulMut(d2 BigDec) BigDec {
d.i.Mul(d.i, d2.i)
d.i = chopPrecisionAndRound(d.i)

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)
return BigDec{d.i}
}

Expand All @@ -360,62 +360,53 @@ func (d BigDec) MulDecMut(d2 Dec) BigDec {
d.i.Mul(d.i, d2.BigIntMut())
d.i = chopPrecisionAndRoundSdkDec(d.i)

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)
return BigDec{d.i}
}

// multiplication truncate
func (d BigDec) MulTruncate(d2 BigDec) BigDec {
mul := new(big.Int).Mul(d.i, d2.i)
chopped := chopPrecisionAndTruncateMut(mul, defaultBigDecPrecisionReuse)

if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(chopped)
return BigDec{chopped}
}

func (d BigDec) MulTruncateDec(d2 Dec) BigDec {
mul := new(big.Int).Mul(d.i, d2.BigIntMut())
chopped := chopPrecisionAndTruncateMut(mul, precisionReuseSDKDec)

if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(chopped)
return BigDec{chopped}
}

// multiplication round up
func (d BigDec) MulRoundUp(d2 BigDec) BigDec {
mul := new(big.Int).Mul(d.i, d2.i)
chopped := chopPrecisionAndRoundUpMut(mul, defaultBigDecPrecisionReuse)
assertMaxBitLen(chopped)
return BigDec{chopped}
}

if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
// multiplication round up by Dec
func (d BigDec) MulRoundUpDec(d2 Dec) BigDec {
mul := new(big.Int).Mul(d.i, d2.BigIntMut())
chopped := chopPrecisionAndRoundUpMut(mul, precisionReuseSDKDec)
assertMaxBitLen(chopped)
return BigDec{chopped}
}

// multiplication
func (d BigDec) MulInt(i BigInt) BigDec {
mul := new(big.Int).Mul(d.i, i.i)

if mul.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(mul)
return BigDec{mul}
}

// MulInt64 - multiplication with int64
func (d BigDec) MulInt64(i int64) BigDec {
bi := big.NewInt(i)
mul := bi.Mul(d.i, bi)

if mul.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(mul)
return BigDec{mul}
}

Expand All @@ -429,38 +420,31 @@ func (d BigDec) Quo(d2 BigDec) BigDec {
// mutative quotient
func (d BigDec) QuoMut(d2 BigDec) BigDec {
// multiply precision twice
// TODO: Use lower overhead thing here
d.i.Mul(d.i, squaredPrecisionReuse)

d.i.Quo(d.i, d2.i)
chopPrecisionAndRound(d.i)

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)
return d
}
func (d BigDec) QuoRaw(d2 int64) BigDec {
// multiply precision, so we can chop it later
// TODO: There is certainly more efficient ways to do this, come back later
mul := new(big.Int).Mul(d.i, defaultBigDecPrecisionReuse)

quo := mul.Quo(mul, big.NewInt(d2))
chopped := chopPrecisionAndRound(quo)

if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(chopped)
return BigDec{chopped}
}

// quotient truncate
func (d BigDec) QuoTruncate(d2 BigDec) BigDec {
// multiply precision twice
mul := new(big.Int).Mul(d.i, defaultBigDecPrecisionReuse)
quo := mul.Quo(mul, d2.i)

if quo.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(quo)
return BigDec{quo}
}

Expand All @@ -469,10 +453,7 @@ func (d BigDec) QuoTruncateMut(d2 BigDec) BigDec {
// multiply bigDec precision
d.i.Mul(d.i, defaultBigDecPrecisionReuse)
d.i.Quo(d.i, d2.i)

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)
return d
}

Expand All @@ -481,10 +462,7 @@ func (d BigDec) QuoTruncateDec(d2 Dec) BigDec {
// multiply Dec Precision
mul := new(big.Int).Mul(d.i, precisionReuseSDKDec)
quo := mul.Quo(mul, d2.BigIntMut())

if quo.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(quo)
return BigDec{quo}
}

Expand All @@ -494,37 +472,53 @@ func (d BigDec) QuoTruncateDecMut(d2 Dec) BigDec {
d.i.Mul(d.i, precisionReuseSDKDec)
d.i.Quo(d.i, d2.BigIntMut())

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
assertMaxBitLen(d.i)
return d
}

// quotient, round up
func (d BigDec) QuoRoundUp(d2 BigDec) BigDec {
// multiply precision twice
mul := new(big.Int).Mul(d.i, squaredPrecisionReuse)
mul := new(big.Int).Mul(d.i, defaultBigDecPrecisionReuse)

quo := mul.Quo(mul, d2.i)
chopped := chopPrecisionAndRoundUpMut(quo, defaultBigDecPrecisionReuse)
chopped, rem := mul.QuoRem(mul, d2.i, new(big.Int))
if rem.Sign() > 0 {
chopped.Add(chopped, oneInt)
}

if chopped.BitLen() > maxDecBitLen {
panic("Int overflow")
assertMaxBitLen(chopped)
return BigDec{chopped}
}

// quotient, round up
func (d BigDec) QuoByDecRoundUp(d2 Dec) BigDec {
mul := new(big.Int).Mul(d.i, precisionReuseSDKDec)

chopped, rem := mul.QuoRem(mul, d2.BigIntMut(), new(big.Int))
if rem.Sign() > 0 {
chopped.Add(chopped, oneInt)
}

assertMaxBitLen(chopped)
return BigDec{chopped}
}

// quotient, round up (mutative)
func (d BigDec) QuoRoundUpMut(d2 BigDec) BigDec {
// multiply precision twice
d.i.Mul(d.i, squaredPrecisionReuse)
d.i.Quo(d.i, d2.i)
d.i.Mul(d.i, defaultBigDecPrecisionReuse)
_, rem := d.i.QuoRem(d.i, d2.i, new(big.Int))

chopPrecisionAndRoundUpMut(d.i, defaultBigDecPrecisionReuse)
d.i = incBasedOnRem(rem, d.i)
assertMaxBitLen(d.i)
return BigDec{d.i}
}

if d.i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
// quotient, round up to next integer (mutative)
func (d BigDec) QuoRoundUpNextIntMut(d2 BigDec) BigDec {
_, rem := d.i.QuoRem(d.i, d2.i, new(big.Int))

d.i = incBasedOnRem(rem, d.i)
d.i.Mul(d.i, defaultBigDecPrecisionReuse)
assertMaxBitLen(d.i)
return BigDec{d.i}
}

Expand Down Expand Up @@ -588,6 +582,12 @@ func (d BigDec) ApproxRoot(root uint64) (guess BigDec, err error) {
return guess, nil
}

func assertMaxBitLen(i *big.Int) {
if i.BitLen() > maxDecBitLen {
panic("Int overflow")
}
}

// ApproxSqrt is a wrapper around ApproxRoot for the common special case
// of finding the square root of a number. It returns -(sqrt(abs(d)) if input is negative.
// TODO: Optimize this to be faster just using native big int sqrt.
Expand Down Expand Up @@ -863,6 +863,13 @@ func chopPrecisionAndRoundUpDec(d *big.Int) *big.Int {
return chopPrecisionAndRoundUpMut(copy, precisionReuseSDKDec)
}

func incBasedOnRem(rem *big.Int, d *big.Int) *big.Int {
if rem.Sign() == 0 {
return d
}
return d.Add(d, oneInt)
}

// chopPrecisionAndRoundUp removes a Precision amount of rightmost digits and rounds up.
// Mutates input d.
// Mutations occur:
Expand All @@ -881,12 +888,7 @@ func chopPrecisionAndRoundUpMut(d *big.Int, precisionReuse *big.Int) *big.Int {

// get the truncated quotient and remainder
_, rem := d.QuoRem(d, precisionReuse, big.NewInt(0))

if rem.Sign() == 0 { // remainder is zero
return d
}

return d.Add(d, oneInt)
return incBasedOnRem(rem, d)
}

func chopPrecisionAndRoundNonMutative(d *big.Int) *big.Int {
Expand Down Expand Up @@ -1211,6 +1213,11 @@ func (d BigDec) PowerInteger(power uint64) BigDec {
func (d BigDec) PowerIntegerMut(power uint64) BigDec {
if power == 0 {
return OneBigDec()
} else if power == 1 {
return d
} else if power == 2 {
// save a oneBigDec allocation
return d.MulMut(d)
}
tmp := OneBigDec()

Expand Down
Loading

0 comments on commit 7b599d5

Please sign in to comment.