Qualche lingua fa la valutazione della mano destra di un'operazione "AND" opzionale?

3

Il linguaggio C # ha due operatori "AND" quando si tratta di valori booleani, & e & & amp ;. (Lasciando da parte gli operatori bit-saggio.)

Quando il valore della mano sinistra è False, la differenza tra questi due operatori riguarda la valutazione dell'operando di destra.

Considera (false && x) rispetto a (false & x)
& & significa che il lato destro non deve essere valutato.
& significa che il lato destro deve essere valutato.

Decenni fa, dovresti sempre utilizzare l'equivalente di & & perché eviterebbe di passare il tempo a elaborare inutilmente quella parte di destra quando già conosciamo la risposta. Al giorno d'oggi, tuttavia, abbiamo CPU che stanno già elaborando la prossima riga di codice prima che la linea precedente abbia finito. Questo deve fermarsi quando viene raggiunto un ramo, quindi potresti voler usare & per evitare quel ramo nel codice e consentire alla CPU di andare avanti senza impedimenti.

(Due barre laterali veloci: A volte, hai bisogno di usare & & perché il lato sinistro protegge da effetti collaterali indesiderati sul lato destro, come il controllo di NULL per evitare un errore di riferimento nullo. Riconoscerò anche che il compilatore può essere abbastanza intelligente da sapere a volte che la mano destra di un & & il funzionamento è privo di effetti collaterali, quindi può eliminare l'istruzione secondaria. Questi sono oltre lo scopo di questa domanda.)

Quindi c'è lo sfondo, ecco la mia domanda.

Ci sono lingue o ambienti che hanno stabilito un compromesso tra & & e & che lascia al compilatore / run-time decidere se il lato destro deve essere valutato?

Dato a AND b , il programmatore direbbe che il compilatore / run-time potrebbe valutare b se un ramo è troppo costoso, ma è anche permesso esplicitamente di ramificarsi attorno al lavoro di valutare b se così facendo sarebbe maggiore del lavoro dell'istruzione branch.

    
posta billpg 28.07.2017 - 19:10
fonte

1 risposta

6

Ci sono linguaggi come Haskell che fanno pochissime garanzie sulla valutazione. Haskell garantisce solo che la valutazione non sia rigorosa, cioè che

f a b = b
f undefined 2

valuta 2 . Questo è praticamente tutto ciò che Haskell garantisce. Qualsiasi (sotto) espressione può essere valutata un numero qualsiasi di volte (o mai).

Tuttavia, le lingue che lo fanno di solito sono pure , il che significa che non si può effettivamente stabilire quante volte sia stata valutata una particolare (sotto) espressione.

Questo avviene anche in alcune CPU superscalari o parallele, dove la condizione di un ramo può dipendere da alcuni dati calcolati da qualche altra CPU (parte della) e non è ancora disponibile, e invece di stallo della pipeline , la CPU eseguirà i rami entrambi e semplicemente eliminerà uno dei due fili di esecuzione non appena la condizione diventa disponibile. Questa è chiamata esecuzione speculativa .

Un'implementazione estremamente aggressiva di questo si trova nelle CPU Itanium di Intel, che su alcuni benchmark possono portare all'80% dei risultati. (Questo è uno dei motivi per cui sono così assetati di potere, dopo tutto, questo significa che produce 5 volte più calore del necessario per calcolare il risultato.)

    
risposta data 28.07.2017 - 19:30
fonte

Leggi altre domande sui tag