Skip to content

Instantly share code, notes, and snippets.

@ghadishayban
Created August 19, 2022 19:23
Show Gist options
  • Save ghadishayban/9bfdc8230cfdcc8f7bad6d3fd8797552 to your computer and use it in GitHub Desktop.
Save ghadishayban/9bfdc8230cfdcc8f7bad6d3fd8797552 to your computer and use it in GitHub Desktop.
luhn with simd
package ghadi;
import jdk.incubator.vector.*;
import java.nio.charset.StandardCharsets;
public class SIMDLuhn {
// assume that credit cards are 16 digits
static final VectorSpecies<Byte> SPECIES = ByteVector.SPECIES_128;
/*
* calculates luhn check digit from 16 digit string
* returns 0 when valid,
* set last digit to 0 if calculating checksum
*/
static int luhn(String s) {
var bs = s.getBytes(StandardCharsets.US_ASCII);
var b = ByteVector.fromArray(SPECIES, bs, 0);
// decode ascii by subtracting 0x30, which is '0'
b = b.sub((byte) 0x30);
// double every other element by adding vector to a masked version of itself
// 0x5555 = 0101010101010101
b = b.add(b, VectorMask.fromLong(SPECIES, 0x5555));
// subtract 9 from any elements that are > 9
// has effect of adding carry digit 12 => 3, 16 => 7
b = b.sub((byte) 9, b.compare(VectorOperators.GT, (byte) 9));
// horizontal addition across all lanes
// add the second half of the vector to the first half,
// then the second quarter of the first half to the first quarter, etc
// Intel intrinsics include _mm_sad_epu8 to do some of this
// but nothing exactly like fold available across platforms
b = b.add(b.rearrange(VectorShuffle.fromValues(SPECIES, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0)));
b = b.add(b.rearrange(VectorShuffle.fromValues(SPECIES, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)));
b = b.add(b.rearrange(VectorShuffle.fromValues(SPECIES, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)));
b = b.add(b.rearrange(VectorShuffle.fromValues(SPECIES, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)));
// sum is in lane 0
int digit = b.lane(0) % 10;
return digit;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment