我一直在編寫一個工具,它可以從SDR設備以高速緩存(每秒1000萬個複雜採樣(樣本是短類型))。但是,隨着我寫的代碼,每當我回頭看寫的內容時,我都會看到一些小塊。C++中的高速緩衝
我試圖緩解這個問題的方法是使用兩個相同大小的緩衝區並在它們之間交換以避免丟失任何樣本。每當我經歷交換緩衝區並將樣本卸載到後臺緩衝區(其大小是採樣速率的3倍)並且如果需要時調用新線程以將新數據寫入到磁盤時,塊會丟失。
SDR設備本身將自己的內部緩衝區大小通告爲2016年的奇怪事物,它給出了實數和虛數採樣數組的兩個指針。很明顯,我想避免這樣的小數組在這個採樣率上的開銷,所以通過實現更大尺寸的交換緩衝區65536,希望我希望能避免這樣的問題,但無濟於事。
我已經指出問題最有可能在回調函數,因爲當我減少交換緩衝區的大小失蹤塊變得更加頻繁。
我是否正在做這個錯誤的方法,或者有更明顯的東西在我的解決方案中缺少,或者我沒有正確書寫一些東西?
我儘可能地避免了標準庫,因爲它對於這種數據速度來說太慢了,因此需要memmove和memcpy。唯一的例外是緩衝區指針交換和創建線程。
交換緩衝器被實現爲:
IQType<short>* bufferA;
IQType<short>* bufferB;
IQType是:
template <class T> class IQType {
public:
T inPhaseValue;
T quadraturePhaseValue;
IQType() : inPhaseValue(0), quadraturePhaseValue(0){};
IQType(T i, T q) : inPhaseValue(i), quadraturePhaseValue(q){};
};
SDR裝置回調函數卸載SDR的示例數據:
void MiricsDataSource::newSamplesCallBack(short *xi, short *xq, unsigned int firstSampleNum, int grChanged, int rfChanged, int fsChanged, unsigned int numSamples, unsigned int reset, void *cbContext) {
MiricsDataSource* mirCtx = static_cast<MiricsDataSource*>(cbContext);
for (int i = 0; i < numSamples; ++i)
{
mirCtx->bufferA[mirCtx->bufferCount] = IQType<short>(xi[i],xq[i]);
mirCtx->bufferCount++;
if(mirCtx->bufferCount == mirCtx->bufferSize-1) {
std::swap(mirCtx->bufferA,mirCtx->bufferB);
mirCtx->owner->backBuffer->write(mirCtx->bufferB,mirCtx->bufferSize);
mirCtx->bufferCount = 0;
}
}
}
後備緩衝寫和相關t_write功能:
void BackBuffer::write(const IQType<short>* buff, size_t bLength) {
std::thread dumpThread(&BackBuffer::t_write,this,buff,bLength);
dumpThread.detach();
}
void BackBuffer::t_write(const IQType<short>* buff, size_t bLength) {
std::lock_guard<std::mutex> lck (bufferMutex);
memmove(&backBuffer[0],(&backBuffer[0])+bLength,(sizeof(IQType<short>*)*(length-bLength)));
memcpy(&backBuffer[length-bLength],buff,(sizeof(IQType<short>*)*(bLength)));
if(dumpToFile) {
IQType<short>* toWrite = new IQType<short>[bLength];
memcpy(toWrite,buff,(sizeof(IQType<short>*)*(bLength)));
strmDmpMgr->write(toWrite,bLength);
}
}
'我儘可能地避免了標準庫,因爲它對於這種數據速度來說太慢了,因此對memmove和memcpy的需求我只是不明白當標準庫當類型在你的情況下是微不足道的時候會執行memcpy/memmove。如果你真的沒有測量它,那麼請刪除該聲明。 – Arunmu
「我儘量避免使用標準庫,因此需要[標準庫中的函數]」似乎有點矛盾。 – user2079303
最初我使用std :: rotate來移動backbuffer,但這樣做需要5秒鐘才能存儲3000萬個樣本。 memmove做這幾百倍更快。只是爲了澄清我用backbuffer中的數據做其他事情而不是記錄。後緩衝器也用於觀察記錄數據的最後3秒。它的處理方式與隊列類似,但可以選擇查看任何位置和任何長度,直到backbuffer的大小。 – Gelion