[WIP] updated the 2 channel synthesizer to use a more SIMD friendly

filter structure.  Updated the channel results array buffer to produce
reusable buffers.

This has dropped the overall memory usage considerably when profiling.

Resolved issue in the processing chain where polyphase channel sources
were not being stopped and were stacking up in memory.
This commit is contained in:
Denny
2018-05-10 08:08:20 -04:00
parent cbc228d798
commit 341e740e77
15 changed files with 257 additions and 115 deletions

View File

@@ -17,7 +17,7 @@ package io.github.dsheirer.sample.buffer;
import io.github.dsheirer.sample.OverflowableTransferQueue;
public class OverflowableReusableBufferTransferQueue<T extends ReusableBuffer> extends OverflowableTransferQueue<T>
public class OverflowableReusableBufferTransferQueue<T extends AbstractReusableBuffer> extends OverflowableTransferQueue<T>
{
/**
* Concurrent transfer queue that couples a higher-throughput linked transfer queue with an atomic integer for

View File

@@ -102,10 +102,7 @@ public class ReusableBuffer extends AbstractReusableBuffer
mUserCount.set(0);
if(mSamples.length != samples.length)
{
mSamples = new float[samples.length];
}
resize(samples.length);
System.arraycopy(samples, 0, mSamples, 0, samples.length);
@@ -129,15 +126,23 @@ public class ReusableBuffer extends AbstractReusableBuffer
mUserCount.set(0);
if(mSamples.length != floatBuffer.capacity())
{
mSamples = new float[floatBuffer.capacity()];
}
resize(floatBuffer.capacity());
floatBuffer.rewind();
floatBuffer.get(mSamples);
mTimestamp = timestamp;
}
/**
* Resizes the internal array to the size argument
* @param size for the internal array
*/
protected void resize(int size)
{
if(mSamples.length != size)
{
mSamples = new float[size];
}
}
}

View File

@@ -107,6 +107,16 @@ public class ReusableBufferAssembler
}
}
/**
* Adds the samples to this assembler. As each buffer is assembled, it will be dispatched to the registered
* listener.
*/
public void receive(ReusableComplexBuffer samplesBuffer)
{
receive(samplesBuffer.getSamples());
samplesBuffer.decrementUserCount();
}
/**
* Flushes the current buffer contents to the registered listener
*/

View File

@@ -51,6 +51,8 @@ public class ReusableBufferQueue extends AbstractReusableBufferQueue<ReusableBuf
mLog.debug("Buffer Created - Count:" + getBufferCount() + (getDebugName() != null ? " [" + getDebugName() + "]" : ""));
}
buffer.resize(size);
return buffer;
}
}

View File

@@ -15,11 +15,17 @@
******************************************************************************/
package io.github.dsheirer.sample.buffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.LinkedList;
import java.util.List;
public class ReusableChannelResultsBuffer extends AbstractReusableBuffer
{
private final static Logger mLog = LoggerFactory.getLogger(ReusableChannelResultsBuffer.class);
private ReusableComplexBufferQueue mReusableComplexBufferQueue =
new ReusableComplexBufferQueue("ReusableChannelResultsBuffer");
private LinkedList<float[]> mEmptyBuffers = new LinkedList<>();
private LinkedList<float[]> mFilledBuffers = new LinkedList<>();
private Integer mLength;
@@ -103,7 +109,7 @@ public class ReusableChannelResultsBuffer extends AbstractReusableBuffer
* @throws IllegalArgumentException if this buffer doesn't contain any samples or if the requested channel is
* not within the channel range of the contained channel results.
*/
public float[] getChannel(int iChannelIndex)
public ReusableComplexBuffer getChannel(int iChannelIndex)
{
if(mFilledBuffers.isEmpty())
{
@@ -116,18 +122,35 @@ public class ReusableChannelResultsBuffer extends AbstractReusableBuffer
"results -- max channel is " + mLength);
}
float[] samples = new float[mFilledBuffers.size() * 2];
ReusableComplexBuffer channelBuffer = mReusableComplexBufferQueue.getBuffer(mFilledBuffers.size() * 2);
float[] samples = channelBuffer.getSamples();
int pointer = 0;
int qChannelIndex = iChannelIndex + 1;
for(float[] channelResults: mFilledBuffers)
{
samples[pointer++] = channelResults[iChannelIndex];
samples[pointer++] = channelResults[qChannelIndex];
try
{
samples[pointer] = channelResults[iChannelIndex];
pointer++;
samples[pointer] = channelResults[qChannelIndex];
pointer++;
}
catch(Exception e)
{
mLog.error("Error accessing channel results - iIndex:" + iChannelIndex +
" Results Size: " + mFilledBuffers.size() +
" Samples Length:" + samples.length +
" Pointer:" + pointer, e);
}
}
return samples;
channelBuffer.incrementUserCount();
return channelBuffer;
}
/**

View File

@@ -58,6 +58,8 @@ public class ReusableComplexBufferQueue extends AbstractReusableBufferQueue<Reus
mLog.debug("Buffer Created - Count:" + getBufferCount() + (getDebugName() != null ? " [" + getDebugName() + "]" : ""));
}
buffer.resize(size);
return buffer;
}
}