Micro-optimizations. Variables limited. Mod2 filter disabled to avoid modulo calculations.
This commit is contained in:
1 parent
e53f0b7a95
commit
3212297911
1 file changed
+46
-40
@@ -1067,6 +1067,7 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
private static void GetQPrefixMask(int startColumn, int qBitLen, int qWordCount, out int words, out ulong lastMask)
|
private static void GetQPrefixMask(int startColumn, int qBitLen, int qWordCount, out int words, out ulong lastMask)
|
||||||
{
|
{
|
||||||
// We want only offsets t <= startColumn.
|
// We want only offsets t <= startColumn.
|
||||||
|
// start column is inclusive for maxT
|
||||||
if (startColumn >= qBitLen - 1)
|
if (startColumn >= qBitLen - 1)
|
||||||
{
|
{
|
||||||
words = qWordCount;
|
words = qWordCount;
|
||||||
@@ -1074,19 +1075,18 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxT = startColumn; // inclusive
|
if (startColumn < 0)
|
||||||
if (maxT < 0)
|
|
||||||
{
|
{
|
||||||
words = 0;
|
words = 0;
|
||||||
lastMask = 0;
|
lastMask = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastWord = maxT >> 6;
|
qBitLen = startColumn >> 6;
|
||||||
words = lastWord + 1;
|
words = qBitLen + 1;
|
||||||
|
|
||||||
int bit = maxT & 63;
|
qWordCount = startColumn & 63;
|
||||||
lastMask = bit == 63 ? ulong.MaxValue : ((1UL << (bit + 1)) - 1UL);
|
lastMask = qWordCount == 63 ? ulong.MaxValue : ((1UL << (qWordCount + 1)) - 1UL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ComputeARangeFromTopConstraints(
|
private static void ComputeARangeFromTopConstraints(
|
||||||
@@ -1214,8 +1214,8 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
|
|
||||||
private static int PowMod2(ulong exp, int mod)
|
private static int PowMod2(ulong exp, int mod)
|
||||||
{
|
{
|
||||||
long result = 1 % mod;
|
long result = 1;
|
||||||
long baseVal = 2 % mod;
|
long baseVal = 2;
|
||||||
ulong value = exp;
|
ulong value = exp;
|
||||||
while (value > 0)
|
while (value > 0)
|
||||||
{
|
{
|
||||||
@@ -1935,14 +1935,16 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
int[][] cache = _stableUnknownDelta8ByUnknown!;
|
int[][] cache = _stableUnknownDelta8ByUnknown!;
|
||||||
|
|
||||||
// Ensure capacity for this "unknown".
|
// Ensure capacity for this "unknown".
|
||||||
int cacheLength = cache.Length;
|
int cacheLength = cache.Length,
|
||||||
|
parity;
|
||||||
|
|
||||||
if ((uint)unknown >= (uint)cacheLength)
|
if ((uint)unknown >= (uint)cacheLength)
|
||||||
{
|
{
|
||||||
// Grow to at least unknown+1, doubling for amortized O(1).
|
// Grow to at least unknown+1, doubling for amortized O(1). parity means newLength here - we're reusing variable to limit registry pressure.
|
||||||
int newLen = cacheLength;
|
parity = cacheLength;
|
||||||
while (newLen <= unknown) newLen <<= 1;
|
while (parity <= unknown) parity <<= 1;
|
||||||
|
|
||||||
var newCache = new int[newLen][];
|
var newCache = new int[parity][];
|
||||||
Array.Copy(cache, newCache, cacheLength);
|
Array.Copy(cache, newCache, cacheLength);
|
||||||
|
|
||||||
// Publish the grown cache (racy publish is OK; contents are immutable after creation).
|
// Publish the grown cache (racy publish is OK; contents are immutable after creation).
|
||||||
@@ -1971,7 +1973,7 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
// 16 iterations correspond to processing 16 columns at once. It was slower with: 32, 128, 1024 and rolled.
|
// 16 iterations correspond to processing 16 columns at once. It was slower with: 32, 128, 1024 and rolled.
|
||||||
for (int i = 0; i < ColumnsAtOnce; i += 4)
|
for (int i = 0; i < ColumnsAtOnce; i += 4)
|
||||||
{
|
{
|
||||||
int parity = (int)(value & 1L);
|
parity = (int)(value & 1L);
|
||||||
int sMax = (((unknown ^ parity) & 1) != 0) ? unknown : (unknown - 1);
|
int sMax = (((unknown ^ parity) & 1) != 0) ? unknown : (unknown - 1);
|
||||||
value = (value + sMax - 1) >> 1;
|
value = (value + sMax - 1) >> 1;
|
||||||
|
|
||||||
@@ -2182,32 +2184,36 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
int aIndex,
|
int aIndex,
|
||||||
int segmentBase,
|
int segmentBase,
|
||||||
int windowSize,
|
int windowSize,
|
||||||
ulong[] knownOne0,
|
in ulong[] knownOne0,
|
||||||
ulong[] knownZero0,
|
in ulong[] knownZero0,
|
||||||
ulong[] knownOne1,
|
in ulong[] knownOne1,
|
||||||
ulong[] knownZero1)
|
in ulong[] knownZero1)
|
||||||
{
|
{
|
||||||
// 0 unknown, 1 one, 2 zero
|
// 0 unknown, 1 one, 2 zero
|
||||||
if (aIndex < 0) return 2;
|
if (aIndex < 0) return 2;
|
||||||
|
int rel, w;
|
||||||
|
ulong m;
|
||||||
if (aIndex >= segmentBase && aIndex < segmentBase + windowSize)
|
if (aIndex >= segmentBase && aIndex < segmentBase + windowSize)
|
||||||
{
|
{
|
||||||
int rel = aIndex - segmentBase;
|
rel = aIndex - segmentBase;
|
||||||
int w = rel >> 6;
|
w = rel >> 6;
|
||||||
ulong m = 1UL << (rel & 63);
|
m = 1UL << (rel & 63);
|
||||||
if ((knownOne0[w] & m) != 0) return 1;
|
if ((knownOne0[w] & m) != 0) return 1;
|
||||||
if ((knownZero0[w] & m) != 0) return 2;
|
if ((knownZero0[w] & m) != 0) return 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int seg1Start = segmentBase - windowSize;
|
|
||||||
if (aIndex >= seg1Start && aIndex < segmentBase)
|
w = segmentBase - windowSize;
|
||||||
|
if (aIndex >= w && aIndex < segmentBase)
|
||||||
{
|
{
|
||||||
int rel = aIndex - seg1Start;
|
rel = aIndex - w;
|
||||||
int w = rel >> 6;
|
w = rel >> 6;
|
||||||
ulong m = 1UL << (rel & 63);
|
m = 1UL << (rel & 63);
|
||||||
if ((knownOne1[w] & m) != 0) return 1;
|
if ((knownOne1[w] & m) != 0) return 1;
|
||||||
if ((knownZero1[w] & m) != 0) return 2;
|
if ((knownZero1[w] & m) != 0) return 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2664,7 +2670,7 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
int forced = 0;
|
int forced = 0;
|
||||||
remaining = 0;
|
remaining = 0;
|
||||||
int chosenIndex = -1;
|
int chosenIndex = -1;
|
||||||
bool topChanged = false;
|
// bool topChanged = false;
|
||||||
bound = (startColumn / windowSize) * windowSize;
|
bound = (startColumn / windowSize) * windowSize;
|
||||||
if (bound != segmentBase)
|
if (bound != segmentBase)
|
||||||
{
|
{
|
||||||
@@ -2883,7 +2889,7 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
}
|
}
|
||||||
|
|
||||||
top0KnownOne = true;
|
top0KnownOne = true;
|
||||||
topChanged = true;
|
// topChanged = true;
|
||||||
}
|
}
|
||||||
else if (chosenIndex == topIndex1)
|
else if (chosenIndex == topIndex1)
|
||||||
{
|
{
|
||||||
@@ -2896,7 +2902,7 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
}
|
}
|
||||||
|
|
||||||
top1KnownOne = true;
|
top1KnownOne = true;
|
||||||
topChanged = true;
|
// topChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2940,17 +2946,17 @@ internal static class BitContradictionSolverWithAMultiplier
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topChanged)
|
// if (topChanged)
|
||||||
{
|
// {
|
||||||
var qHash = ComputeQOffsetsHash(qOneOffsets);
|
// var qHash = ComputeQOffsetsHash(qOneOffsets);
|
||||||
if (!TryDynamicModularRangePrune(qOneOffsets, qHash, prime, maxAllowedA, top0KnownOne, top0KnownZero, top1KnownOne, top1KnownZero, zeroTailStart))
|
// if (!TryDynamicModularRangePrune(qOneOffsets, qHash, prime, maxAllowedA, top0KnownOne, top0KnownZero, top1KnownOne, top1KnownZero, zeroTailStart))
|
||||||
{
|
// {
|
||||||
#if DETAILED_LOG
|
// #if DETAILED_LOG
|
||||||
reason = ContradictionReason.ParityUnreachable;
|
// reason = ContradictionReason.ParityUnreachable;
|
||||||
#endif
|
// #endif
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ((top0KnownZero && top0KnownOne) || (top1KnownZero && top1KnownOne))
|
if ((top0KnownZero && top0KnownOne) || (top1KnownZero && top1KnownOne))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user