Motore di raccolta delle statistiche per i sistemi C ++

1

Abbiamo un progetto di ricerca con il ciclo di sviluppo delle statistiche prototipo- e gt; Ad ogni modo, il nostro prodotto finale è un prototipo, quindi la suite di raccolta delle statistiche è non usato in modo persistente. Supponendo che abbia la seguente classe:

class Transform {
    private:
        someData;

    public:
        transformForward (inp_block, outp_block);
        transformBackward (inp_block, outp_block);
};

Immagina di far parte di un grande sistema. Ho bisogno di raccogliere periodicamente alcune statistiche su tale trasformazione (anche i dati interni potrebbero essere considerati). Sembra che l'aggiunta di routine statistiche sarebbe una violazione del principio di responsabilità singola. Il secondo odore è che non voglio toccare il codice che usa Transform istanze per invocare esplicitamente queste routine. Sarei meglio se potessi attivare un qualche tipo di interruttore in modo che vengano raccolte le statistiche per quel modulo.

Ho incontrato questa sfida un numero di volte e ho la sensazione di reinventare costantemente la ruota. Esistono alcune buone pratiche per la configurazione e la raccolta della suite di statistiche per un sistema composto senza interferire con il suo codice interno?

UPDATE:

Come posso vedere dalle risposte proposte, la mia domanda è troppo aspecifica, quindi fornirò un esempio più concreto.

Considera un sistema di compressione delle immagini composto da due blocchi enormi : Predictor e Encoder . Ci sono molti algoritmi di predizione e compressione, durante la nostra ricerca abbiamo bisogno di esplorare il comportamento dei componenti in varie condizioni. Dovremmo rispondere a domande come "quante volte il pixel viene elaborato all'interno di ciascun contesto", "quanto bene funziona questo predittore", "in che modo ciascun predittore influenza lo stato interno di Encoder " e molti altri.

In ogni caso, il nostro prodotto finale è solo un Codec con nessuna suite statistica fornita con esso; tutti i tipi di raccolta di statistiche vengono utilizzati internamente durante la nostra ricerca. Quindi sorge la domanda: come si può costruire un motore di statistica flessibile che conosca gli interni del sistema? Come si potrebbe mantenere il sistema stesso indipendente dal motore di statistiche?

    
posta ownclo 09.05.2013 - 01:42
fonte

2 risposte

1

Il pattern Observer potrebbe essere una buona idea qui. La classe Transform definisce un insieme di eventi che potrebbero interessare il motore di statistiche e il motore di statistica si registra con l'istanza Transform pertinente per raccogliere le statistiche su tale trasformazione (o le statistiche che includono tale trasformazione).

Aggiorna

Come affermato in un commento, il problema di base è come il motore di statistica sa che è successo qualcosa di interessante. Potresti eseguire il codec in una macchina virtuale per tenere traccia di tutto (valgrind usa questo approccio per controllare l'accesso alla memoria), ma poi hai il problema di decidere cosa significa che l'indirizzo di accesso al codec 0x12345678 .

Tutti gli altri metodi di raccolta delle statistiche invadono il codice base del codec in un modo o nell'altro. Il meno invasivo è probabilmente quello di aggiungere una quantità copiosa di registrazione e di lasciarlo analizzare dal motore di statistica. Tutti i pacchetti di registrazione forniscono anche i mezzi per disabilitare la generazione dei registri con un costo minimo, a volte anche compilando tali istruzioni in modalità no-op.

    
risposta data 09.05.2013 - 13:45
fonte
1

Se lo stato interno dell'implementazione della trasformazione non è considerato, Decorator sembra essere la risposta. Altrimenti, vedi risposta di Bart van Ingen Schenau .

Prima che ciò possa accadere, sono necessari due refactoring sulla base di codice esistente :

  • Crea un'interfaccia per i metodi delle classi Transform . Questa è Astrazione .
  • Il codice esistente che utilizza le classi Transform deve consentire al codice di livello superiore di specificare quale implementazione di TransformInterface deve essere utilizzata. Questa è Iniezione di dipendenza .

Una classe decoratore responsabile per l'acquisizione di statistiche dai dati che entrano e escono dall'interfaccia Transform :

  • Implementa l'interfaccia Transform
  • Decora (avvolgente) un'implementazione concreta di Transform
  • Avere metodi transformForward e transformBackward che raccolgono i dati, quindi inoltrare la chiamata all'implementazione concreta.

class TransformInterface
{
public: 
virtual ~TransformInterface() = 0; virtual void transformForward ( ... ) = 0; virtual void transformBackward ( ... ) = 0; }; class TransformStatisticsGatherer : public TransformInterface { public: TransformStatisticsGatherer( TransformInterface * pConcreteTransform ) { myConcreteTransform = pConcreteTransform; } void transformForward ( void* inputBlock, void* outputBlock ) { ... // do something with inputBlock and outputBlock _before_ the call myConcreteTransform -> transformForward ( inputBlock, outputBlock ); ... // do something with inputBlock and outputBlock after_ the call } void transformBackward ( void* inputBlock, void* outputBlock ) { ... // do something with inputBlock and outputBlock _before_ the call myConcreteTransform -> transformBackward ( inputBlock, outputBlock ); ... // do something with inputBlock and outputBlock _after_ the call } void getStatistics ( ... ) { ... // return the gathered statistics } private: TransformInterface* myConcreteTransform; ... // additional private fields for statistics gathering };
    
risposta data 09.05.2013 - 08:55
fonte

Leggi altre domande sui tag