Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e8171eb8f32d
Choose a base ref
...
head repository: ngscopeclient/scopehal-apps
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 585ac7de61de
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on May 10, 2020

  1. Copy the full SHA
    fa3a381 View commit details
  2. OscilloscopeWindow: RefreshAllDecoders() now uses OpenMP parallelism …

    …between non-dependent decodes. Fixes #39.
    azonenberg committed May 10, 2020
    Copy the full SHA
    585ac7d View commit details
Showing with 83 additions and 28 deletions.
  1. +80 −28 glscopeclient/OscilloscopeWindow.cpp
  2. +3 −0 glscopeclient/OscilloscopeWindow.h
108 changes: 80 additions & 28 deletions glscopeclient/OscilloscopeWindow.cpp
Original file line number Diff line number Diff line change
@@ -404,15 +404,6 @@ void OscilloscopeWindow::CloseSession()
//Purge our list of scopes (the app will delete them)
m_scopes.clear();

//Clear performance counters
m_tAcquire = 0;
m_tDecode = 0;
m_tView = 0;
m_tHistory = 0;
m_tPoll = 0;
m_tEvent = 0;
m_lastWaveformTimes.clear();

//Close stuff in the application, terminate threads, etc
g_app->ShutDownSession();
}
@@ -466,7 +457,18 @@ void OscilloscopeWindow::OnFileOpen()
void OscilloscopeWindow::DoFileOpen(string filename, bool loadLayout, bool loadWaveform, bool reconnect)
{
m_currentFileName = filename;

CloseSession();

//Clear performance counters
m_tAcquire = 0;
m_tDecode = 0;
m_tView = 0;
m_tHistory = 0;
m_tPoll = 0;
m_tEvent = 0;
m_lastWaveformTimes.clear();

try
{
auto docs = YAML::LoadAllFromFile(m_currentFileName);
@@ -1695,26 +1697,84 @@ void OscilloscopeWindow::OnWaveformDataReady(Oscilloscope* scope)
//Update the status
UpdateStatusBar();

RefreshAllDecoders();

//Update protocol analyzers
for(auto a : m_analyzers)
a->OnWaveformDataReady();

//Update the history window
m_historyWindows[scope]->OnWaveformDataReady();

m_tHistory += GetTime() - start;
}

void OscilloscopeWindow::RefreshAllDecoders()
{
//Update the measurements
//TODO: remove this when we finish unification of measurements and decodes
for(auto g : m_waveformGroups)
g->RefreshMeasurements();

//Update our protocol decoders
start = GetTime();
double start = GetTime();

for(auto d : m_decoders)
d->SetDirty();

//Prepare to topologically sort filter nodes into blocks capable of parallel evaluation.
//Block 0 may only depend on physical scope channels.
//Block 1 may depend on decodes in block 0 or physical channels.
//Block 2 may depend on 1/0/physical, etc.
typedef vector<ProtocolDecoder*> DecodeBlock;
vector<DecodeBlock> blocks;
set<OscilloscopeChannel*> working;

//Working set starts out as all decoders
for(auto d : m_decoders)
d->RefreshIfDirty();
m_tDecode += GetTime() - start;
working.emplace(d);

//Update protocol analyzers
for(auto a : m_analyzers)
a->OnWaveformDataReady();
//Each iteration, put all decodes that only depend on previous blocks into this block.
for(int block=0; !working.empty(); block++)
{
DecodeBlock current_block;

//Update the history window
m_historyWindows[scope]->OnWaveformDataReady();
for(auto w : working)
{
ProtocolDecoder* d = static_cast<ProtocolDecoder*>(w);

m_tHistory += GetTime() - start;
//Check if we have any inputs that are still in the working set.
bool ok = true;
for(size_t i=0; i<d->GetInputCount(); i++)
{
auto in = d->GetInput(i);
if(working.find(in) != working.end())
{
ok = false;
break;
}
}

//All inputs are in previous blocks, we're good to go for the current block
if(ok)
current_block.push_back(d);
}

//Anything we assigned this iteration shouldn't be in the working set for next time.
//It does, however, have to get saved in the output block.
for(auto d : current_block)
working.erase(d);
blocks.push_back(current_block);
}

//Evaluate the blocks, taking advantage of parallelism between them
for(auto& block : blocks)
{
#pragma omp parallel for
for(size_t i=0; i<block.size(); i++)
block[i]->RefreshIfDirty();
}

m_tDecode += GetTime() - start;
}

void OscilloscopeWindow::UpdateStatusBar()
@@ -1785,15 +1845,7 @@ void OscilloscopeWindow::OnHistoryUpdated(bool refreshAnalyzers)
//Stop triggering if we select a saved waveform
OnStop();

//Update the measurements
for(auto g : m_waveformGroups)
g->RefreshMeasurements();

//Update our protocol decoders
for(auto d : m_decoders)
d->SetDirty();
for(auto d : m_decoders)
d->RefreshIfDirty();
RefreshAllDecoders();

//Update the views
for(auto w : m_waveformAreas)
3 changes: 3 additions & 0 deletions glscopeclient/OscilloscopeWindow.h
Original file line number Diff line number Diff line change
@@ -198,6 +198,9 @@ class OscilloscopeWindow : public Gtk::Window
void OnEyeColorChanged(EyeColor color, Gtk::RadioMenuItem* item);
void OnTriggerProperties(Oscilloscope* scope);

//Protocol decoding etc
void RefreshAllDecoders();

virtual bool on_delete_event(GdkEventAny* any_event);

Glib::RefPtr<Gtk::CssProvider> m_css;