Quanto dovrebbe essere ottimizzato il software scientifico?


13

Per le applicazioni che richiedono risorse computazionali significative, le prestazioni elevate possono essere un fattore critico quando si tratta di fornire risultati scientifici o raggiungere "innovazioni" in tempi ragionevoli.

Quanto tempo e sforzi dovrebbero investire gli sviluppatori software nell'ottimizzazione di un'applicazione? Quali sono i criteri chiave utilizzati?


I programmi che scienziati scrivono spesso corrono per molto tempo (ad esempio, simulazioni). Il tempo del programmatore e il tempo di esecuzione del computer potrebbero essere comparabili. Questo è molto diverso dal "solito" lavoro del programmatore di oggi. Come nei primi tempi dell'informatica, spesso vale la pena investire qualche sforzo (e tempo del programmatore) per rendere la simulazione più veloce e terminare più rapidamente e completare il lavoro più velocemente.
Szabolcs,

Risposte:


15

Nella stragrande maggioranza dei casi, miglioramenti in algoritmi fanno una differenza maggiore rispetto al miglioramento dell'ottimizzazione. Gli algoritmi sono anche più portabili delle ottimizzazioni di basso livello. Il mio consiglio è di seguire le migliori pratiche generali per quanto riguarda il layout di memoria per il riutilizzo della cache, evitando copie o comunicazioni eccessive, trattando il file system in modo sano e facendo in modo che i kernel in virgola mobile abbiano una granularità sufficiente per la vettorializzazione. A volte questo è sufficiente per raggiungere una frazione accettabilmente alta di "picco" (per questa operazione).

Disegna sempre un modello di prestazione per le operazioni che ritieni importanti (o che ritieni importanti mediante la profilazione). Quindi è possibile utilizzare il modello delle prestazioni per stimare ciò che un'implementazione altamente ottimizzata potrebbe offrire. Se decidi che ne vale la pena (rispetto alle altre cose che potresti fare), allora ottimizza.

Forse la sfida più difficile è progettare interfacce e strutture di dati di alto livello (nel senso che molto codice dipenderà da queste scelte) in modo da poterle ottimizzare in seguito senza dover modificare l'API. Contrariamente a ottimizzazioni specifiche e linee guida generali, non so come insegnarlo se non attraverso l'esperienza. Lavorare con un software open source sensibile alle prestazioni aiuta. Come per qualsiasi decisione sull'API, è importante comprendere lo spazio del problema.


1
Proprio di recente ho ottenuto un fattore di miglioramento di 10.000 (per i nostri eventi più grandi) nel tempo di esecuzione di una fase limitante della nostra analisi, sostituendo un algoritmo che era O (n ^ 2) nel tempo e nello spazio con una O (n log n ) in entrambe. Intendiamoci, significava un'altra dipendenza e una certa complessità aggiunta, ma a volte ne vale la pena ...
dmckee --- ex gattino moderatore

1
I fattori di accelerazione (che sono relativi a qualcosa) non valgono molto un chiaro riferimento a ciò che hai confrontato. Se si confronta con una cattiva implementazione basata su un algoritmo inappropriato e poi si cambia, ovviamente non sarebbe irragionevole aspettarsi grandi guadagni relativi.
Allan P. Engsig-Karup,

1
@Allan: c'era un fattore di 10.000 da ottenere da un singolo cambiamento, quindi ovviamente era un'implementazione scelta male. Il codice precedente era danneggiato tanto dallo spazio inutile quanto dalla complessità temporale: le prestazioni della cache erano spaventose. Ma è questo il punto, no?
dmckee --- ex gattino moderatore

8

Come definiresti "ottimizzare"? C'è un intero spettro dallo sviluppo di algoritmi o modelli computazionali migliori fino all'uso di assemblatori sintonizzati a mano.

Secondo la mia opinione ed esperienza, il frutto basso è da qualche parte nel mezzo, ad esempio la scelta di un algoritmo che si adatta meglio all'architettura del computer sottostante. L'algoritmo non deve necessariamente essere nuovo e la tua comprensione dell'architettura sottostante non deve necessariamente essere molto specifica, ad es

  • Se sai che la tua architettura supporta SIMD, riformula il calcolo in modo che le tue operazioni possano essere scritte in termini di vettori brevi,
  • Se sai che l'architettura è un computer multi-core, prova a suddividere l'attività computazionale in singole attività secondarie che non interferiscono tra loro ed eseguirle in parallelo (pensa a un DAG delle tue attività secondarie) ,
  • Se la tua architettura sottostante ha una GPU, pensa a come puoi riformulare il tuo calcolo come un gruppo di thread che marciano attraverso i dati in blocco,
  • eccetera...

Tutte le funzionalità di cui sopra, ad esempio SIMD, parallelismo e GPU, sono accessibili senza conoscenze di basso livello, ma offrono davvero un vantaggio in algoritmi in grado di sfruttarle facilmente.


4

Sono d'accordo con tutte le risposte già presentate finora ... Voglio solo affrontare un altro aspetto trascurato dell'ottimizzazione del codice: l'aspettativa di qualità.

Il problema dell'ottimizzazione del codice sorge in genere quando l'utente cerca di risolvere problemi sempre più grandi e il codice è insufficiente per soddisfare le esigenze / aspettative dell'utente. Il tempo che si dovrebbe investire nell'ottimizzazione del codice dipende dalla domanda per soddisfare questa aspettativa. Vale sicuramente la pena di dedicare molto tempo se vi è la necessità critica di un vantaggio competitivo (ad esempio, terminare e pubblicare la tua ricerca su un argomento caldo prima degli altri).

Ovviamente, quanto tempo dovrebbe essere investito dipende da quanto velocemente è necessario e da quanto portatile si desidera che il codice sia. Spesso, queste due esigenze sono in conflitto tra loro e devi decidere quale è più importante prima di iniziare l'ottimizzazione. Più portatile lo desideri, più devi fare affidamento su modifiche di progettazione di alto livello al codice (algoritmo / struttura dati). Più veloce si desidera eseguire il codice, deve essere ottimizzato con ottimizzazioni di basso livello specifiche per una determinata macchina (ad es. Ottimizzazioni di codice / compilatore / runtime).


4

Dovrai fare l'analisi (di costo) di spendere così tanti mesi-uomo (e quelli sono sempre mitici :-)) per ottenere velocità di esecuzione. Dovrai capire quante volte verrà utilizzato questo software e da quante persone puoi stimare il guadagno.

La regola empirica, come sempre, è la famosa regola 80/20. Ad un certo momento non si somma più per passare sempre più tempo a guadagnare poche percentuali (o meno) di tempo di esecuzione. Ma dovrai analizzare.

E sono sinceramente d'accordo con i poster sopra: assicurati che la tua API sia ben pensata, quindi non ha bisogno di molte modifiche e assicurati che il codice sia portatile e gestibile (pensa a dover analizzare nuovamente un algoritmo che hai scritto e nitido ottimizzato dieci anni fa). E assicurati di usare buone pratiche di programmazione e librerie standard. È probabile che qualcuno abbia già pensato all'algoritmo più efficiente per la tua applicazione.

Per citare Donald Knuth: "l'ottimizzazione prematura è la radice di tutti i mali". Quindi profila il tuo codice, ma non troppo presto.


Ti riferisci alla regola del principio di Pareto (80/20)? In tal caso, vuoi dire che dovremmo concentrare gli sforzi di ottimizzazione sul 20% del codice che produce l'80% del rallentamento? O vuoi dire che se puoi aspettarti solo il 20% di accelerazione, allora non vale la pena ottimizzare?
Paul

No, l'ho usato solo come una specie di principio, non esattamente 80/20. Ad un certo momento, spenderai così tanto sforzo per guadagnare solo poche percentuali che non vale più la pena.
GertVdE,

3

Alcuni consigli aggiuntivi:

  1. Prima di eseguire qualsiasi ottimizzazione di un programma di lavoro, assicurati di disporre di una buona serie di casi di test che aiutano a mantenere l'integrità del codice. Non ha senso ottenere risultati sbagliati più velocemente.
  2. Se la tua ottimizzazione rende il codice meno leggibile, mantieni la versione originale, almeno sotto forma di un commento, ma meglio come versione alternativa da selezionare in fase di compilazione e di esecuzione. Le tue esigenze di ottimizzazione possono cambiare man mano che i tuoi problemi e le tue macchine evolvono e il codice originale potrebbe essere un punto di partenza migliore per l'ottimizzazione che farai tra cinque anni.
  3. Se la tua versione ottimizzata risulta avere un impatto minimo, ma rende il codice meno leggibile, meno universale o meno stabile, torna alla versione originale. Perdi più di quanto guadagni.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.