Allocatore di memoria


11

Stai progettando un nuovo linguaggio di programmazione esoterico e una caratteristica che hai deciso di aggiungere è un allocatore di memoria dinamica. La tua lingua specifica uno spazio di indirizzi virtuale dedicato speciale per lo spazio del programma dell'utente. Questo è separato dallo spazio degli indirizzi utilizzato dall'allocatore di memoria per qualsiasi stato interno.

Per aiutare a ridurre i costi di distribuzione dell'implementazione, la dimensione del codice deve essere il più piccola possibile.

Interfaccia

È necessario fornire tre funzioni: inizializzazione, allocazione e deallocazione.

Inizializzazione

Questa funzione accetta un singolo parametro intero positivo N. Ciò significa che il programma di un utente ha Nbyte nel suo spazio di indirizzi da cui ci sono N-1byte da cui allocare memoria. L'indirizzo 0è riservato per "null".

È garantito che questa funzione verrà chiamata esattamente una volta prima di qualsiasi chiamata di allocazione / deallocazione.

Si noti che questa funzione non ha bisogno di allocare memoria fisica per lo spazio degli indirizzi virtuali del programma utente; stai fondamentalmente creando il "look and feel" di un allocatore di memoria vuoto.

assegnare

La funzione di allocazione deve accettare una richiesta del numero di byte di memoria da allocare. L'input è garantito per essere positivo.

La funzione deve restituire un indirizzo intero all'inizio del blocco allocato o 0per indicare che non è disponibile alcun blocco contiguo della dimensione richiesta. Se un blocco contiguo delle dimensioni disponibili è disponibile in qualsiasi punto dello spazio degli indirizzi, è necessario allocare!

È necessario assicurarsi che non si sovrappongano due blocchi allocati.

Dealloca

La funzione deallocazione deve prendere un indirizzo dell'inizio di un blocco allocato e, facoltativamente, può anche prendere la dimensione del blocco dato.

La memoria che è stata deallocata è di nuovo disponibile per l'allocazione. Si presume che l'indirizzo di input sia un indirizzo valido.

Esempio di implementazione di Python

Si noti che è possibile scegliere qualsiasi metodo per tenere traccia dello stato interno; in questo esempio l'istanza di classe ne tiene traccia.

class myallocator:
    def __init__(self, N):
        # address 0 is special, it's always reserved for null
        # address N is technically outside the address space, so use that as a
        # marker
        self.addrs = [0, N]
        self.sizes = [1, 0]

    def allocate(self, size):
        for i,a1,s1,a2 in zip(range(len(self.addrs)),
                                 self.addrs[:-1], self.sizes[:-1],
                                 self.addrs[1:]):
            if(a2 - (a1+s1) >= size):
                # enough available space, take it
                self.addrs.insert(i+1, a1+s1)
                self.sizes.insert(i+1, size)
                return a1+s1
        # no contiguous spaces large enough to take our block
        return 0

    def deallocate(self, addr, size=0):
        # your implementation has the option of taking in a size parameter
        # in this implementation it's not used
        i = self.addrs.index(addr)
        del self.addrs[i]
        del self.sizes[i]

punteggio

Questo è il codice golf; vince il codice più breve in byte. Non devi preoccuparti di rimanere senza memoria per qualsiasi stato interno richiesto dal tuo allocatore.

Si applicano fori ad anello standard.

Classifica


3
Dubito che le liste di Python occupino esattamente un byte per elemento. La "memoria allocata" deve essere in byte o può essere semplicemente "il tipo di array / elenco generico della tua lingua"?
Maniglia della porta

4
Non è richiesta alcuna allocazione effettiva (ad eccezione di ciò che si desidera per il monitoraggio dello stato interno, che si trova sul proprio spazio di indirizzi virtuale); stai solo restituendo numeri interi ad un certo spazio di indirizzi virtuale finito astratto.
helloworld922,

To help reduce the cost of distributing your implementation the size of the code must be as small as possibleo potrebbe essere efficiente (piccolo ed efficiente non è lo stesso) possibile? : D
The Coder


Mentre questa sfida è motivata da un background di progettazione linguistica, la progettazione di una lingua non fa effettivamente parte dell'attività (piuttosto implementa parti di una), quindi ho rimosso il tag.
Martin Ender,

Risposte:


4

Ruby, 80 anni

i,a,d=->n{$m=?o*n},->n{$m.sub!(/\B#{?o*n}/,?f*n);"#$`".size},->n,s{$m[n,s]=?o*s}

Come la risposta di MegaTom, ma utilizza una stringa anziché un array per memorizzare lo stato. Il carattere "o" indica una cella aperta, mentre una "f" indica una cella piena. Questo ci consente di utilizzare le funzioni di manipolazione delle stringhe relativamente concise di Ruby:

?o*n inizializza una stringa di n "o" s.

/\B#{?o*n}/è un'espressione regolare che corrisponde a "o" s consecutive che non include il primo carattere. sub!sostituisce la prima corrispondenza con n "f" s.

"#$`" fornisce la stringa a sinistra della corrispondenza o una stringa vuota se non vi era corrispondenza, quindi la dimensione è l'indice allocato o 0.

Deallocate riporta semplicemente la sezione designata della stringa su "o" s.


4

JavaScript (ES6), 88

Utilizzo di una variabile globale _(un array molto scarso) per tenere traccia.

Ora come potrei provarlo?

I=n=>(_=[1],_[n]=0)
A=n=>_.some((x,i)=>i-p<n?(p=i+x,0):_[p]=n,p=1)?p:0
D=p=>delete _[p]

3

Ruby, 135

Ha un array globale per tenere traccia dell'allocazione o meno di ogni cella.

i=->n{$a=[!0]*n;$a[0]=0}
a=->n{s=$a.each_cons(n).to_a.index{|a|a.none?};n.times{|i|$a[s+i]=0}if s;s||0}
d=->s,n{n.times{|i|$a[s+i]=!0}}

1

Mathematica, 152

i=(n=#;l={{0,1},{#,#}};)&
a=If[#=={},0,l=l~Join~#;#[[1,1]]]&@Cases[l,{Except@n,e_}:>{e,e+#}/;Count[l,{a_,_}/;e<=a<e+#]<1,1,1]&
d=(l=l~DeleteCases~{#,_};)&

nmemorizzare la dimensione totale, lmemorizza lo stato interno. L'allocatore tenterà di allocare subito dietro un'altra sezione della memoria allocata.

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.