Improve performance & responsiveness of sim updates.
The x-axis only needs to be fetched once per update. Same for redrawing the screen. And there's no reason to fetch more y data than we have x data for (which happens to subsequent traces as the sim is still running as we're updating). Fixes https://gitlab.com/kicad/code/kicad/-/issues/15673
This commit is contained in:
parent
da1405ec6a
commit
463e7c3b30
|
@ -913,8 +913,6 @@ void SIM_PLOT_TAB::SetTraceData( TRACE* trace, std::vector<double>& aX, std::vec
|
||||||
if( cursor )
|
if( cursor )
|
||||||
cursor->SetCoordX( cursor->GetCoords().x );
|
cursor->SetCoordX( cursor->GetCoords().x );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_plotWin->UpdateAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1057,6 +1057,8 @@ void SIMULATOR_FRAME_UI::onSignalsGridCellChanged( wxGridEvent& aEvent )
|
||||||
else
|
else
|
||||||
plotTab->DeleteTrace( vectorName, traceType );
|
plotTab->DeleteTrace( vectorName, traceType );
|
||||||
|
|
||||||
|
plotTab->GetPlotWin()->UpdateAll();
|
||||||
|
|
||||||
// Update enabled/visible states of other controls
|
// Update enabled/visible states of other controls
|
||||||
updateSignalsGrid();
|
updateSignalsGrid();
|
||||||
updatePlotCursors();
|
updatePlotCursors();
|
||||||
|
@ -1529,6 +1531,8 @@ void SIMULATOR_FRAME_UI::AddTrace( const wxString& aName, SIM_TRACE_TYPE aType )
|
||||||
updateTrace( aName, aType, plotTab );
|
updateTrace( aName, aType, plotTab );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plotTab->GetPlotWin()->UpdateAll();
|
||||||
|
|
||||||
updateSignalsGrid();
|
updateSignalsGrid();
|
||||||
m_simulatorFrame->OnModify();
|
m_simulatorFrame->OnModify();
|
||||||
}
|
}
|
||||||
|
@ -1606,7 +1610,7 @@ void SIMULATOR_FRAME_UI::SetUserDefinedSignals( const std::map<int, wxString>& a
|
||||||
|
|
||||||
|
|
||||||
void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceType,
|
void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceType,
|
||||||
SIM_PLOT_TAB* aPlotTab )
|
SIM_PLOT_TAB* aPlotTab, std::vector<double>* aDataX )
|
||||||
{
|
{
|
||||||
SIM_TYPE simType = SPICE_CIRCUIT_MODEL::CommandToSimType( aPlotTab->GetSimCommand() );
|
SIM_TYPE simType = SPICE_CIRCUIT_MODEL::CommandToSimType( aPlotTab->GetSimCommand() );
|
||||||
|
|
||||||
|
@ -1626,51 +1630,60 @@ void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceTyp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, handle the x axis
|
|
||||||
wxString xAxisName( simulator()->GetXAxis( simType ) );
|
|
||||||
|
|
||||||
if( xAxisName.IsEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::vector<double> data_x;
|
std::vector<double> data_x;
|
||||||
std::vector<double> data_y;
|
std::vector<double> data_y;
|
||||||
|
|
||||||
data_x = simulator()->GetGainVector( (const char*) xAxisName.c_str() );
|
if( !aDataX )
|
||||||
|
aDataX = &data_x;
|
||||||
|
|
||||||
|
// First, handle the x axis
|
||||||
|
if( aDataX->empty() )
|
||||||
|
{
|
||||||
|
wxString xAxisName( simulator()->GetXAxis( simType ) );
|
||||||
|
|
||||||
|
if( xAxisName.IsEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
*aDataX = simulator()->GetGainVector( (const char*) xAxisName.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int size = aDataX->size();
|
||||||
|
|
||||||
switch( simType )
|
switch( simType )
|
||||||
{
|
{
|
||||||
case ST_AC:
|
case ST_AC:
|
||||||
if( aTraceType & SPT_AC_GAIN )
|
if( aTraceType & SPT_AC_GAIN )
|
||||||
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str() );
|
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str(), size );
|
||||||
else if( aTraceType & SPT_AC_PHASE )
|
else if( aTraceType & SPT_AC_PHASE )
|
||||||
data_y = simulator()->GetPhaseVector( (const char*) simVectorName.c_str() );
|
data_y = simulator()->GetPhaseVector( (const char*) simVectorName.c_str(), size );
|
||||||
else
|
else
|
||||||
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or AC_MAG bit" ) );
|
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or AC_MAG bit" ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case ST_SP:
|
case ST_SP:
|
||||||
if( aTraceType & SPT_SP_AMP )
|
if( aTraceType & SPT_SP_AMP )
|
||||||
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str() );
|
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str(), size );
|
||||||
else if( aTraceType & SPT_AC_PHASE )
|
else if( aTraceType & SPT_AC_PHASE )
|
||||||
data_y = simulator()->GetPhaseVector( (const char*) simVectorName.c_str() );
|
data_y = simulator()->GetPhaseVector( (const char*) simVectorName.c_str(), size );
|
||||||
else
|
else
|
||||||
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
|
wxFAIL_MSG( wxT( "Plot type missing AC_PHASE or SPT_SP_AMP bit" ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_NOISE:
|
|
||||||
case ST_DC:
|
case ST_DC:
|
||||||
|
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str(), -1 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ST_NOISE:
|
||||||
case ST_TRAN:
|
case ST_TRAN:
|
||||||
case ST_FFT:
|
case ST_FFT:
|
||||||
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str() );
|
data_y = simulator()->GetGainVector( (const char*) simVectorName.c_str(), size );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( wxT( "Unhandled plot type" ) );
|
wxFAIL_MSG( wxT( "Unhandled plot type" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int size = data_x.size();
|
|
||||||
|
|
||||||
// If we did a two-source DC analysis, we need to split the resulting vector and add traces
|
// If we did a two-source DC analysis, we need to split the resulting vector and add traces
|
||||||
// for each input step
|
// for each input step
|
||||||
SPICE_DC_PARAMS source1, source2;
|
SPICE_DC_PARAMS source1, source2;
|
||||||
|
@ -1684,9 +1697,9 @@ void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceTyp
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
size_t outer = ( size_t )( ( source2.m_vend - v ) / source2.m_vincrement ).ToDouble();
|
size_t outer = ( size_t )( ( source2.m_vend - v ) / source2.m_vincrement ).ToDouble();
|
||||||
size_t inner = data_x.size() / ( outer + 1 );
|
size_t inner = aDataX->size() / ( outer + 1 );
|
||||||
|
|
||||||
wxASSERT( data_x.size() % ( outer + 1 ) == 0 );
|
wxASSERT( aDataX->size() % ( outer + 1 ) == 0 );
|
||||||
|
|
||||||
for( size_t idx = 0; idx <= outer; idx++ )
|
for( size_t idx = 0; idx <= outer; idx++ )
|
||||||
{
|
{
|
||||||
|
@ -1694,8 +1707,8 @@ void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceTyp
|
||||||
{
|
{
|
||||||
if( data_y.size() >= size )
|
if( data_y.size() >= size )
|
||||||
{
|
{
|
||||||
std::vector<double> sub_x( data_x.begin() + offset,
|
std::vector<double> sub_x( aDataX->begin() + offset,
|
||||||
data_x.begin() + offset + inner );
|
aDataX->begin() + offset + inner );
|
||||||
std::vector<double> sub_y( data_y.begin() + offset,
|
std::vector<double> sub_y( data_y.begin() + offset,
|
||||||
data_y.begin() + offset + inner );
|
data_y.begin() + offset + inner );
|
||||||
|
|
||||||
|
@ -1710,7 +1723,7 @@ void SIMULATOR_FRAME_UI::updateTrace( const wxString& aVectorName, int aTraceTyp
|
||||||
else if( TRACE* trace = aPlotTab->AddTrace( aVectorName, aTraceType ) )
|
else if( TRACE* trace = aPlotTab->AddTrace( aVectorName, aTraceType ) )
|
||||||
{
|
{
|
||||||
if( data_y.size() >= size )
|
if( data_y.size() >= size )
|
||||||
aPlotTab->SetTraceData( trace, data_x, data_y );
|
aPlotTab->SetTraceData( trace, *aDataX, data_y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2676,8 +2689,10 @@ void SIMULATOR_FRAME_UI::OnSimRefresh( bool aFinal )
|
||||||
|
|
||||||
for( const auto& [ trace, traceInfo ] : traceMap )
|
for( const auto& [ trace, traceInfo ] : traceMap )
|
||||||
{
|
{
|
||||||
|
std::vector<double> data_x;
|
||||||
|
|
||||||
if( !traceInfo.first.IsEmpty() )
|
if( !traceInfo.first.IsEmpty() )
|
||||||
updateTrace( traceInfo.first, traceInfo.second, plotTab );
|
updateTrace( traceInfo.first, traceInfo.second, plotTab, &data_x );
|
||||||
}
|
}
|
||||||
|
|
||||||
plotTab->GetPlotWin()->UpdateAll();
|
plotTab->GetPlotWin()->UpdateAll();
|
||||||
|
|
|
@ -238,7 +238,8 @@ private:
|
||||||
* @param aTraceType describes the type of plot.
|
* @param aTraceType describes the type of plot.
|
||||||
* @param aPlotTab is the tab that should receive the update.
|
* @param aPlotTab is the tab that should receive the update.
|
||||||
*/
|
*/
|
||||||
void updateTrace( const wxString& aVectorName, int aTraceType, SIM_PLOT_TAB* aPlotTab );
|
void updateTrace( const wxString& aVectorName, int aTraceType, SIM_PLOT_TAB* aPlotTab,
|
||||||
|
std::vector<double>* aDataX = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rebuild the list of signals available from the netlist.
|
* Rebuild the list of signals available from the netlist.
|
||||||
|
|
Loading…
Reference in New Issue