Domanda

Guardando a questa domanda: Perché un C / C ++ necessario conoscere la dimensione di un array al momento della compilazione? è venuto in mente che gli esecutori compilatore dovrebbe hanno avuto alcune volte per ottenere i loro piedi bagnati ora (parte di essa la standard C99 , che è di 10 anni fa) e di fornire implementazioni efficienti.

Tuttavia sembra ancora (dalle risposte) per essere considerato costoso.

Questo mi sorprende in qualche modo.

Naturalmente, capisco che un offset statica è molto meglio di una dinamica uno in termini di prestazioni, e diversamente da un suggerimento non avrei effettivamente avere il compilatore eseguire un'allocazione mucchio di matrice dal momento che questo sarebbe probabilmente costato ancora di più [ questo non è stato misurato;)]

Ma io sono ancora sorpreso il presunto costo :

  • se non c'è VLA in una funzione, allora non ci sarebbe alcun costo, per quanto posso vedere.
  • se v'è un unico VLA, allora si può neanche metterlo prima o dopo tutte le variabili, e quindi ottenere un offset per la maggior parte dello stack frame statico (o almeno così sembra a me, ma io non sono ben versato nella gestione dello stack)

La domanda si pone di più i VLA, naturalmente, e mi chiedevo se avere uno stack VLA dedicato avrebbe funzionato. Questo mezzo di un VLA sarebbero rappresentati da un conteggio e un puntatore (di dimensioni note quindi) e la memoria effettiva presa in uno stack secondario utilizzato solo per questo scopo (e quindi veramente una pila troppo).

[riformulare]

Come i VLA sono implementati in gcc / VC ++?

è il costo davvero così impressionante?

[riformulazione fine]

Mi sembra che possa essere solo meglio di, diciamo, un vector, anche con le implementazioni attuali, dal momento che non sostenere il costo di un'allocazione dinamica (a costo di non essere ridimensionabile).

Modifica

C'è una risposta parziale qui , tuttavia confrontando i VLA per array tradizionali sembrano ingiusto . Se conoscessimo la dimensione in anticipo, quindi non avremmo bisogno di un VLA. Nella stessa domanda AndreyT ha dato alcune indicazioni per quanto riguarda l'attuazione, ma non è preciso come vorrei.

È stato utile?

Soluzione

  

Come i VLA sono implementati in gcc / VC ++?

Per quanto ne sappia VC ++ non implementa VLA. Si tratta di un compilatore C ++ e supporta solo C89 (senza VLA, non limitano). Non so come utensileria gcc VLA ma il modo più veloce possibile è quello di memorizzare il puntatore alla VLA e la dimensione in sezione statica della stack-frame. In questo modo è possibile accedere a una delle VLA con prestazioni di un array costante dimensioni (è l'ultima VLA se lo stack cresce verso il basso come in x86 (dereferenziazione [stack pointer + indice * dimensione dell'elemento + la dimensione delle ultime spinte temporanee]), e il primo VLA se cresce verso l'alto (dereferenziazione [puntatore stackframe + offset da stackframe + indice * dimensione dell'elemento])). Tutti gli altri VLA avranno bisogno ancora un'indirezione di ottenere il loro indirizzo di base dalla parte statica della pila.

[ Modifica: anche quando si utilizza il compilatore VLA può puntatore allo stack-frame-base, omettere che è ridondante altrimenti, perché tutti gli offset di puntatore di stack possono essere calcolati durante la fase di compilazione. In modo da avere un registro meno libero. - Modifica end ]

  

È il costo davvero così impressionante?

Non proprio. Inoltre, se non ne fanno uso, non si paga per esso.

[ Modifica: Probabilmente una risposta più corretta sarebbe: rispetto a cosa? Rispetto ad un mucchio allocato vettore, il tempo di accesso sarà lo stesso ma l'allocazione e deallocazione sarà più veloce. - Modifica end ]

Altri suggerimenti

Se dovesse essere attuato in VC ++, mi assumo la squadra compilatore avrebbe usato qualche variante del _alloca(size). E Credo che il costo è equivalente all'utilizzo variabili con maggiore allineamento a 8 byte in pila (come __m128); il compilatore deve memorizzare l'originale stack pointer da qualche parte, e allineando la pila richiede un registro in più per memorizzare lo stack non allineato.

Quindi, l'overhead è fondamentalmente un riferimento indiretto in più (è necessario memorizzare l'indirizzo del VLA da qualche parte) e registrarsi pressione dovuta a memorizzare la gamma pila da qualche parte originale pure.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top