Skip to content

Commit

Permalink
#10 - 128bit concurrent code working to 63
Browse files Browse the repository at this point in the history
  • Loading branch information
obriensystems committed Jan 4, 2025
1 parent 961cb9d commit 7ea3259
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/**
* 20250101
* Michael O'Brien michael at obrienlabs.dev
* Code from https://github.com/ObrienlabsDev/performance
*
* Architecture
* map the search space by interleaved UOW (1,3,5,7) - to 4 threads
Expand Down Expand Up @@ -117,7 +118,8 @@ public void searchCollatzParallel(long oddSearchCurrent, long secondsStart) {
.filter(num -> isCollatzMax(num, secondsStart))
.collect(Collectors.toList());

results.stream().sorted().forEach(x -> System.out.println(x));
results.stream().forEach(x -> System.out.println(x)); // fix comparable in https://github.com/ObrienlabsDev/performance/issues/27
//results.stream().sorted().forEach(x -> System.out.println(x));
}
System.out.println("last number: " + ((1 + (batches) * threads) - 1));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,54 @@ public boolean isEven() {

@Override
public boolean isGreaterThan(ULong128 ulong128) {
return false;
// check high (fast exit), then low
int topCompare = Long.compareUnsigned(this.long1, ulong128.getLong1());

if(topCompare < 0) {
return false;
} else {
if(topCompare > 0) {
return true;
} else {
int lowCompare = Long.compareUnsigned(this.long0, ulong128.getLong0());
if(lowCompare < 0) {
return false;
} else {
if(lowCompare > 0) {
return true;
} else {
return false;
}
}
}
}
}

@Override
// we add the low bytes, detect the carry, add the high bytes and add the carry
public ULong128 add(ULong128 ulong128) {;
long temp0 = this.getLong0() + ulong128.getLong0();
long temp0 = this.long0 + ulong128.getLong0();
// a smaller result means we experienced overflow
long carry0 = Long.compareUnsigned(temp0, this.getLong0()) < 0 ? 1L : 0L;
long temp1 = this.getLong1() + ulong128.getLong1() + carry0;
long temp1 = this.long1 + ulong128.getLong1() + carry0;
return new ULong128Impl(temp1, temp0);
}

@Override
// use >>> triple shift to fill 0's on the right
public ULong128 shiftLeft(int positions) {
ULong128 result = this;
return result;
// we only shift one digit
return this.add(this);
}

@Override
// use >>> triple shift to fill 0's on the right
public ULong128 shiftRight(int positions) {
ULong128 result = this;
return result;
// multiply by 2 until we have the last LSB shifted to MSBit left position
long highShiftedLeft63BitsInPrepOfAddToLow = this.long1 << 63;//(64 - positions);
long temp0 = (this.long0 >>> 1) + highShiftedLeft63BitsInPrepOfAddToLow ;
long temp1 = this.long1 >>> 1;
return new ULong128Impl(temp1, temp0);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.obrienlabs.performance.nbi;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -50,4 +51,59 @@ void test128bitAddAtBit31NoOverflow() {
assertTrue(c.getLong1() == expected.getLong1());
assertTrue(c.getLong0() == expected.getLong0());
}

@Test
void testGreaterThanDoubleLongTrue() {
ULong128 a = new ULong128Impl(1L, Long.MAX_VALUE); // 2^31-1 = 9223372036854775807
ULong128 b = new ULong128Impl(0L, 65536L);
assertTrue(a.isGreaterThan(b));
}

@Test
void testGreaterThanDoubleLongFalse() {
ULong128 a = new ULong128Impl(1L, Long.MAX_VALUE); // 2^31-1 = 9223372036854775807
ULong128 b = new ULong128Impl(0L, 65536L);
assertFalse(b.isGreaterThan(a));
}

@Test
void testGreaterThanSingleLongTrue() {
ULong128 a = new ULong128Impl(0L, Long.MAX_VALUE - 2L); // 2^31-1 = 9223372036854775807
ULong128 b = new ULong128Impl(0L, 65536L);
assertTrue(a.isGreaterThan(b));
}

@Test
void testGreaterThanSingleLongFalse() {
ULong128 a = new ULong128Impl(0L, Long.MAX_VALUE - 2L); // 2^31-1 = 9223372036854775807
ULong128 b = new ULong128Impl(0L, 65536L);
assertFalse(b.isGreaterThan(a));
}

@Test
void test128bitShiftLeftWithoutOverflow() {
ULong128 a = new ULong128Impl(2L, 3L);
ULong128 expected = new ULong128Impl(4L, 6L);
ULong128 c = a.shiftLeft(1);
assertTrue(c.getLong1() == expected.getLong1());
assertTrue(c.getLong0() == expected.getLong0());
}

@Test
void test128bitShiftRightWithOverflow() {
ULong128 a = new ULong128Impl(1L, 1L);
ULong128 expected = new ULong128Impl(0L, -(Long.MAX_VALUE + 1));
ULong128 c = a.shiftRight(1);
assertTrue(c.getLong1() == expected.getLong1());
assertTrue(c.getLong0() == expected.getLong0());
}

@Test
void test128bitShiftRightWithOverflow2() {
ULong128 a = new ULong128Impl(170L, 170L);
ULong128 expected = new ULong128Impl(85L, 85L);
ULong128 c = a.shiftRight(1);
assertTrue(c.getLong1() == expected.getLong1());
assertTrue(c.getLong0() == expected.getLong0());
}
}

0 comments on commit 7ea3259

Please sign in to comment.