Questo argomento può essere sufficiente?

1

Abbiamo due classi C ++ denominate Important e Small

La classe Small usa alcuni metodi e attributi dalla classe Important , ma non tutti.

Poiché la nostra applicazione è critica dal punto di vista delle prestazioni, invece di copiare tutti gli attributi (possibilmente puntatori) di Important necessari per Small e ridefinire i pochi metodi in Small , abbiamo deciso di lasciare che Small tenga premuto puntatore su Important .

Le prestazioni possono giustificare una tale scelta di design?

    
posta Issam T. 16.04.2014 - 18:12
fonte

2 risposte

0

In linea con RAII, farei sicuramente in modo di avere un puntatore intelligente conteggio di riferimento ( shared_ptr ) invece di un puntatore raw. Oltre a ciò, non c'è nulla di intrinsecamente sbagliato in quello che hai descritto.

Tuttavia, come molte persone hanno già notato, è impossibile dare una risposta precisa senza due cose:

  • Codice. Stai trasformando il tuo codice in un pasticcio incomprensibile quando c'è un'opzione più semplice? Che diamine se lo so. Non ho visto il tuo codice. Non sto chiedendo il codice (non lo leggerò anche se me lo hai dato), ma ti chiedo di prendere questo consiglio con un pizzico di sale. Solo perché ho detto che non c'era nulla di sbagliato non significa che sia giusto.
  • Numeri di prestazione. È davvero qualcosa che influenzerà le prestazioni del tuo programma? Senza numeri solidi non posso dire con certezza e nè puoi .
risposta data 16.04.2014 - 19:21
fonte
0

Can performance justify such a design choice?

Con così poche informazioni, penso che il consiglio verrà spinto verso suggerimenti di profilazione e misurazione e avvertimenti sull'ottimizzazione prematura. Ma cercherò di darti il beneficio del dubbio.

Applichiamo una mentalità progettuale orientata ai dati che inizia con l'idea della rappresentazione dei dati più ottimale, e ci avvicina alle interfacce da lì. L'aspetto più utile di questo esercizio saranno le interfacce pubbliche che progettiamo, la considerazione delle rappresentazioni dei dati è principalmente quella di garantire un'interfaccia che possa lasciare spazio alle ottimizzazioni senza rotture a cascata nel sistema.

Design orientato ai dati

Since our application is performance critical, instead of copying all attributes (possibly pointers) of Important that are needed by Small and redefine the few methods in Small, we decided to just let Small hold a pointer on Important.

Alcune ipotesi che farò per restringere l'ambito:

  • C'è un carico di queste istanze Small* .
  • La fase di inizializzazione in cui vengono creati come un sottoinsieme di dati Important's è separata e al di fuori dei percorsi di codice critici, non interlacciati (altrimenti il tuo suggerimento esistente potrebbe essere il percorso migliore).
  • Il percorso critico sta eseguendo un ciclo di caricamento di queste istanze Small .
  • I campi di Important stesso, al di fuori del sottoinsieme rappresentato da Small , sono freddi.
  • I campi di Important non cambiano dopo il passo di inizializzazione (le loro punte potrebbero cambiare se ci sono campi puntatore, ma gli indirizzi del puntatore non cambierebbero).

One-to-One

A condizione che esista una relazione uno-a-uno di un sottoinsieme Small*'s di campi di dati a un Important (nessuna ridondanza), in genere il modo più veloce è copiare e duplicare effettivamente i dati di Important in piccolo.

Poiché Important è dati a freddo in base ai nostri presupposti, che consente a Small di assumere una natura più contigua e che un numero maggiore dei dati pertinenti si adatti a una riga della cache senza essere mescolato con dati irrilevanti.

Many-to-One

Se ciò è sbagliato e c'è molta risonanza tra Small* istanze (cioè una relazione molti-a-uno tra Small riferimenti a un campo Important ), quindi duplicare i dati potrebbe fare più danni che buona.

In tal caso, il puntamento a Important può iniziare a mostrare un vantaggio favorevole, dato che stiamo giocando a una località temporale con Important campi spesso seduti in una linea della cache e riducendo Small in basso alla dimensione di un puntatore singolo.

Per duplicare o non duplicare

Quindi la scelta se duplicare o meno dipende dal livello di ridondanza e se la fase di inizializzazione di un piccolo è al di fuori dei percorsi critici. Se vuoi sapere a quale livello di ridondanza, considera la dimensione totale di tutte le istanze Small* se quei campi da Important sono stati duplicati. Se la dimensione non è maggiore della somma di tutti i campi Important , copiare i campi pertinenti su Small potrebbe essere una scommessa sicura (a condizione che non sia necessario accedere a Important nei percorsi critici, che sia veramente freddo dopo quel punto).

Con poca o nessuna ridondanza e Important a freddo, allora la suddivisione del campo hot / cold in realtà con ridondanza per ottenere il lato caldo della suddivisione può effettivamente aiutare molto (per quanto intuitiva possa sembrare).

Ultimo ma non meno importante, dovrebbe esserci un carico di barca di Small* istanze istanziate e accessibili. Se non ci sono, allora questo è preoccupante per qualcosa che non dovrebbe essere preoccupato, dato che probabilmente trarrai un vantaggio molto dalla localizzazione temporale in entrambi i casi.

    
risposta data 23.12.2015 - 07:11
fonte

Leggi altre domande sui tag