-
Notifications
You must be signed in to change notification settings - Fork 525
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make
GeoHash
coordinate conversions ~40-100x faster (#348)
* Refactor Haversine-distance calculation * See https://github.com/dotnet/runtime/blob/333fb71d54bd84256e740aa08f8b836d4cd71d98/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs#L65-L113 * Do not spill the coordinate ranges to heap when encoding/decoding * Keep them in registers (or atmost spill to stack) * Also some other misc. simplification * Add shared AsciiUtils to Garnet.common to simplify the unit conversions * Slightly adjust GeoHash tests * dotnet format * Restore flag bit for GetGeoHashCode for now * I will return to this method in a follow-up * Optimize GeoToLongValue to use float quantization trick and do the Z-curve encoding more directly * Credits to https://mmcloughlin.com/posts/geohash-assembly for the quantization approach! * Further optimize Geohash & Base32 encoding and decoding * Abuse IEEE-754 binary representation in the encoding too * Implement Z-curve decoding more efficiently * Add GetGeoErrorByPrecision to calculate the error at given bit precision (52 for us). * Optimize base32 string encoding. * Test still fail. Will need to investigate more. * typo * Further clarify the quantization method * Calculate the center of bounding-box * Clarify dequantization method * Make the bounding-box center fix-up use constants * Add more test-data and restore original epsilon calc. * tests: sqc8b49rnyt -> sqc8b49rnys * tests: nsqdtr74hyu1 -> nsqdtr74hyu0 * Exponent is 1023, not 0 * Add USE_PDEP_PEXT switch for PDEP/PEXT Z-curve en/decode * And define it to run the tests with it * Use FusedMultiplyAdd to do (x+y)*z in one op to avoid intermediate rounding * More accurate and faster, what not to love * Remove #define USE_PDEP_PEXT, tests passed * Move GeoHash specific unit tests own file * Mark Z-curve encode/decode with MethodImpl.AI * Little extra encouragement to JIT. * Add GeoHash specific benchmarks * oops * format * Add UsePdepPext build switch. * And add GeoHashBenchmark job with it enabled * Avoid shifting by using already shifted mask for the PDEP/PEXT * Use AVX512 support to guard PDEP/PEXT usage. * Add MemoryDiagnoser back * Fix incorrect quantization approach * Make it little bit more clear what happens in the corner-case guard * We might not even wan't cmov/csel which might stall out-of-order execution. Doesn't matter what is emitted tbh. * Remove not needed pow2 trick * Let JIT do its thing, it's pretty good * Adjust comments a bit * Fix comment typos * Adjust comments * Adjust comments * Add third-party notices to NOTICE.md * The GeoHash class incorporates material from mmcloughlin/geohash and georust/geohash, both licensed under MIT License. Thank you for sharing! --------- Co-authored-by: Yoganand Rajasekaran <60369795+yrajas@users.noreply.github.com>
- Loading branch information
1 parent
5c4041e
commit e0027d1
Showing
10 changed files
with
441 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using BenchmarkDotNet.Attributes; | ||
|
||
using Garnet.server; | ||
|
||
namespace BDN.benchmark | ||
{ | ||
[MemoryDiagnoser] | ||
public class GeoHashBenchmarks | ||
{ | ||
private const double Latitude = 47.642219912251285; | ||
private const double Longitude = -122.14205560231471; | ||
|
||
private const long GeoHashInteger = 1557413161902764; | ||
|
||
[Benchmark] | ||
public long GeoToLongValue() => GeoHash.GeoToLongValue(Latitude, Longitude); | ||
|
||
[Benchmark] | ||
public (double, double) GetCoordinatesFromLong() => GeoHash.GetCoordinatesFromLong(GeoHashInteger); | ||
|
||
[Benchmark] | ||
public string GetGeoHashCode() => GeoHash.GetGeoHashCode(GeoHashInteger); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,33 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
using BenchmarkDotNet.Columns; | ||
using BenchmarkDotNet.Configs; | ||
using BenchmarkDotNet.Environments; | ||
using BenchmarkDotNet.Exporters; | ||
using BenchmarkDotNet.Jobs; | ||
using BenchmarkDotNet.Loggers; | ||
using BenchmarkDotNet.Running; | ||
|
||
var config = DefaultConfig.Instance | ||
.AddJob(Job.Default | ||
.WithRuntime(CoreRuntime.Core60) | ||
.WithId(".NET 6")) | ||
.AddJob(Job.Default | ||
.WithRuntime(CoreRuntime.Core80) | ||
.WithEnvironmentVariables(new EnvironmentVariable("DOTNET_TieredPGO", "0")) | ||
.WithId(".NET 8")); | ||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new BaseConfig()); | ||
|
||
BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, config); | ||
public class BaseConfig : ManualConfig | ||
{ | ||
public Job Net6BaseJob { get; } | ||
public Job Net8BaseJob { get; } | ||
|
||
public BaseConfig() | ||
{ | ||
AddLogger(ConsoleLogger.Default); | ||
AddExporter(DefaultExporters.Markdown); | ||
AddColumnProvider(DefaultColumnProviders.Instance); | ||
|
||
var baseJob = Job.Default.WithGcServer(true); | ||
|
||
Net6BaseJob = baseJob.WithRuntime(CoreRuntime.Core60); | ||
Net8BaseJob = baseJob.WithRuntime(CoreRuntime.Core80) | ||
.WithEnvironmentVariables(new EnvironmentVariable("DOTNET_TieredPGO", "0")); | ||
|
||
AddJob(Net6BaseJob.WithId(".NET 6"), Net8BaseJob.WithId(".NET 8")); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
namespace Garnet.common; | ||
|
||
/// <summary> | ||
/// Utilites for ASCII parsing and manipulation. | ||
/// </summary> | ||
public static class AsciiUtils | ||
{ | ||
public static byte ToLower(byte value) | ||
{ | ||
if ((uint)(value - 'A') <= (uint)('Z' - 'A')) // Is in [A-Z] | ||
value = (byte)(value | 0x20); | ||
return value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.