Micro-optimizations. Variables limited. Mod2 filter disabled to avoid modulo calculations.

This commit is contained in:
mlemanczyk committed 2026-01-20 21:49:27 +01:00
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))
{ {