From 2c69fa284baa540a65e487da0c439b6a6b3adce0 Mon Sep 17 00:00:00 2001
From: Vojtech Moravec <vojtech.moravec.st@vsb.cz>
Date: Tue, 4 Feb 2020 09:40:20 +0100
Subject: [PATCH] Parallelized quantizeIntoIndices for VQ compression.
---
.../compression/VQImageCompressor.java | 2 +-
.../quantization/vector/VectorQuantizer.java | 42 +++++++++++++++++--
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/src/main/java/azgracompress/compression/VQImageCompressor.java b/src/main/java/azgracompress/compression/VQImageCompressor.java
index de00719..33cadff 100644
--- a/src/main/java/azgracompress/compression/VQImageCompressor.java
+++ b/src/main/java/azgracompress/compression/VQImageCompressor.java
@@ -143,7 +143,7 @@ public class VQImageCompressor extends CompressorDecompressorBase implements IIm
assert (quantizer != null);
Log("Compression plane...");
- final int[] indices = quantizer.quantizeIntoIndices(planeVectors);
+ final int[] indices = quantizer.quantizeIntoIndices(planeVectors, options.getWorkerCount());
try (OutBitStream outBitStream = new OutBitStream(compressStream, options.getBitsPerPixel(), 2048)) {
outBitStream.write(indices);
diff --git a/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java b/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
index 72b4f1e..adb9b52 100644
--- a/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
+++ b/src/main/java/azgracompress/quantization/vector/VectorQuantizer.java
@@ -31,13 +31,47 @@ public class VectorQuantizer {
}
public int[] quantizeIntoIndices(final int[][] dataVectors) {
+ return quantizeIntoIndices(dataVectors, 1);
+ }
+
+
+ public int[] quantizeIntoIndices(final int[][] dataVectors, final int maxWorkerCount) {
+
assert (dataVectors.length > 0 && dataVectors[0].length % vectorSize == 0) : "Wrong vector size";
int[] indices = new int[dataVectors.length];
- // Speedup
- for (int vectorIndex = 0; vectorIndex < dataVectors.length; vectorIndex++) {
- indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex],
- VectorDistanceMetric.Euclidean);
+ if (maxWorkerCount == 1) {
+ for (int vectorIndex = 0; vectorIndex < dataVectors.length; vectorIndex++) {
+ indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex],
+ VectorDistanceMetric.Euclidean);
+ }
+ } else {
+ // Cap the worker count on 8
+ final int workerCount = Math.min(maxWorkerCount, 8);
+ Thread[] workers = new Thread[workerCount];
+ final int workSize = dataVectors.length / workerCount;
+
+ for (int wId = 0; wId < workerCount; wId++) {
+ final int fromIndex = wId * workSize;
+ final int toIndex = (wId == workerCount - 1) ? dataVectors.length : (workSize + (wId * workSize));
+
+ workers[wId] = new Thread(() -> {
+ for (int vectorIndex = fromIndex; vectorIndex < toIndex; vectorIndex++) {
+ indices[vectorIndex] = findClosestCodebookEntryIndex(dataVectors[vectorIndex],
+ VectorDistanceMetric.Euclidean);
+ }
+ });
+
+ workers[wId].start();
+ }
+ try {
+ for (int wId = 0; wId < workerCount; wId++) {
+ workers[wId].join();
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
}
return indices;
}
--
GitLab