Mostra notizie nelle discussioni
  • Avatar
    ☺
    Scritto da
    altg
    utente che non utiene
    il 2014-10-29 19:40:05.0 alle 2014-10-29 19:40:05.0
    Trollate totali: 11540
    Ci si capisce, vero?
    Ci si capisce un casino!
    E` tutto molto espressivo e ovvio. Ficoso

            include rc
            include text
            nameset text
    
    
            to From ByteString r    "binaural fn
            to From ByteString      "monaural fn
            
                creates a text object from a byte-aligned null-terminated string,
                such as those built by the compiler e.g. when you type @8:{ Hello! },
                or generally read from ASCII files (does not support UTF-8; another
                function will probably be developed for that, once someone provides
                means to render the characters outside the historical ASCII range...)
    
                    --> m = firstByte       (byte select mask)
                    --> n = R               (first unit in source buffer)
                    --> p = r               (start address in source buffer)
                    --> q                   (future start address in target buffer)
                    --> r = 0               (source bytes counter, starts at zero)
                    
                    repeat if n has m       (as long as no null terminator found)
    
                            r + 1           (increment bytes counter)
                            m ] 8           (rotate mask, e.g. FF000000 -> 00FF0000)
                            
                            if m eq firstByte
                            
                                    p + 1   (access next unit in source buffer)
                                    n = P   (load new source buffer unit)
    
                    <-- p                   (p = entry r, i.e. initial source address)
    
                    q <- rc::Pick r Units   (q = target buffer)
                    r <- rc::Size Of q      (r = back to abovely determined byte-size)
                    
                    --> q                   (will be returned to caller)
                    --> v = firstByte       (free register v, use as byte select mask)
                    
                    m = 0                   (rotation magnitude, starts at zero)
                    
                    r times                 (each byte in source)
    
                            m + 8           (increase rotation: make that 8 for first byte)
                            n = P           (read current source unit)
                            n & v           (mask off all bytes except the relevant one)
                            n [ m           (rotate the relevant byte to its place, i.e...)
                            Q = n           (left-most of the target unit, hereby written)
                            
                            if m eq bitsPerUnit
                            
                                    p + 1   (full circle? ok, access next unit in source)
                                    m = 0   (and reset rotation magnitude)
    
                            q + 1           (access next unit in target buffer)
                            v ] 8           (rotate mask, e.g. FF000000 -> 00FF0000)
                    
                    <-- v                   (restore v - it's callers' vicinity pointer)
                    <-- r                   (we had stacked target buffer before v)
                    <-- q                   (callee-saved)
                    <-- p                   (callee-saved)
                    <-- n                   (callee-saved)
                    <-- m                   (callee-saved)
                    
                    return r                (we return the target buffer address)
    


    Oh ma comunque una cosa del genere (conversione di una stringa ASCII da un allineamento a 8 bit a uno a 32 bit per carattere), penso sarebbe piuttosto oscura anche se la scrivessi in javascript. Comunque ho commentato tutto, il che spiega molte cose e non sto affatto prendendo per il culo, no, cosa andate mai a pensare? A bocca storta

    Vabbe' ragazzi, ovviamente poi uno 'ste cose se le trova pronte e le chiama e basta. Cioe` in un esempio da tutorial, 'sta roba e` solo usata, non scritta, il che viene fuori piu` comprensibilmente cosi`:

    	startup displayStatus engage
    	include text fromByteString
    	include text say
    	include util pause
    
    
    	to Begin
    
    		text::From ByteString @8:{ Hello } -> Say
    
    		each P inside \
    
    		[
    
    			@8:{ _Mercury		},
    			@8:{ _Venus		},
    			@8:{ _Earth		},
    			@8:{ _Mars		},
    			@8:{ _Jupiter		},
    			@8:{ _Saturn		},
    			@8:{ _Uranus		},
    			@8:{ _Neptune		},
    			@8:{ _and_maybe_Pluto	}
    
    		]
    
    			text::From ByteString P -> Say
    
    		util::Pause
    		leave
    


    E qui dai si capisce.
    Testo::daStringaDiBytes @8:{ questa } -> Dillo
    Dove @8 imposta la wordsize, cioe` gli dice fai 8 bit per carattere.
    Per default la fa lunga un'unita`, cioe` una parola della CPU, cioe` 32 bit qui.
    E poi "per ogni P in un array di stringhe di bytes", fai la stessa cosa con P.
    Pausa e poi chiudi il programma.
    L'output e` ovviamente "Hello Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune and maybe Pluto".
    Ah, gli underscore nelle stringhe marcano gli spazi.
    Dai che si capisce, dai, non mi puoi dire... no? come no? In lacrime
    • Avatar
      Scritto da
      Non Autenticato
      il 2014-10-29 20:05:42.0 alle 2014-10-29 20:05:42.0
      Re: Ci si capisce, vero?
      Scritto da: altg
      > Ci si capisce un casino!
      > E` tutto molto espressivo e ovvio. Ficoso
      >
      >
      > include rc
      > include text
      > nameset text
      > 
      > 
      > to From ByteString r    "binaural fn
      > to From ByteString      "monaural fn
      > 
      > creates a text object from a byte-aligned null-terminated string,
      > such as those built by the compiler e.g. when you type @8:{ Hello! },
      > or generally read from ASCII files (does not support UTF-8; another
      > function will probably be developed for that, once someone provides
      > means to render the characters outside the historical ASCII range...)
      > 
      > --> m = firstByte       (byte select mask)
      > --> n = R               (first unit in source buffer)
      > --> p = r               (start address in source buffer)
      > --> q                   (future start address in target buffer)
      > --> r = 0               (source bytes counter, starts at zero)
      > 
      > repeat if n has m       (as long as no null terminator found)
      > 
      > r + 1           (increment bytes counter)
      > m ] 8           (rotate mask, e.g. FF000000 -> 00FF0000)
      > 
      > if m eq firstByte
      > 
      > p + 1   (access next unit in source buffer)
      > n = P   (load new source buffer unit)
      > 
      > <-- p                   (p = entry r, i.e. initial source address)
      > 
      > q <- rc::Pick r Units   (q = target buffer)
      > r <- rc::Size Of q      (r = back to abovely determined byte-size)
      > 
      > --> q                   (will be returned to caller)
      > --> v = firstByte       (free register v, use as byte select mask)
      > 
      > m = 0                   (rotation magnitude, starts at zero)
      > 
      > r times                 (each byte in source)
      > 
      > m + 8           (increase rotation: make that 8 for first byte)
      > n = P           (read current source unit)
      > n & v           (mask off all bytes except the relevant one)
      > n [ m           (rotate the relevant byte to its place, i.e...)
      > Q = n           (left-most of the target unit, hereby written)
      > 
      > if m eq bitsPerUnit
      > 
      > p + 1   (full circle? ok, access next unit in source)
      > m = 0   (and reset rotation magnitude)
      > 
      > q + 1           (access next unit in target buffer)
      > v ] 8           (rotate mask, e.g. FF000000 -> 00FF0000)
      > 
      > <-- v                   (restore v - it's callers' vicinity pointer)
      > <-- r                   (we had stacked target buffer before v)
      > <-- q                   (callee-saved)
      > <-- p                   (callee-saved)
      > <-- n                   (callee-saved)
      > <-- m                   (callee-saved)
      > 
      > return r                (we return the target buffer address)
      > 

      >
      > Oh ma comunque una cosa del genere (conversione di una stringa ASCII da un allineamento a 8 bit a uno a 32 bit per carattere), penso sarebbe piuttosto oscura anche se la scrivessi in javascript. Comunque ho commentato tutto, il che spiega molte cose e non sto affatto prendendo per il culo, no, cosa andate mai a pensare? A bocca storta
      >
      > Vabbe' ragazzi, ovviamente poi uno 'ste cose se le trova pronte e le chiama e basta. Cioe` in un esempio da tutorial, 'sta roba e` solo usata, non scritta, il che viene fuori piu` comprensibilmente cosi`:
      >
      >
      > 	startup displayStatus engage
      > 	include text fromByteString
      > 	include text say
      > 	include util pause
      > 
      > 
      > 	to Begin
      > 
      > 		text::From ByteString @8:{ Hello } -> Say
      > 
      > 		each P inside \
      > 
      > 		[
      > 
      > 			@8:{ _Mercury		},
      > 			@8:{ _Venus		},
      > 			@8:{ _Earth		},
      > 			@8:{ _Mars		},
      > 			@8:{ _Jupiter		},
      > 			@8:{ _Saturn		},
      > 			@8:{ _Uranus		},
      > 			@8:{ _Neptune		},
      > 			@8:{ _and_maybe_Pluto	}
      > 
      > 		]
      > 
      > 			text::From ByteString P -> Say
      > 
      > 		util::Pause
      > 		leave
      > 

      >
      > E qui dai si capisce.
      > Testo::daStringaDiBytes @8:{ questa } -> Dillo
      > Dove @8 imposta la wordsize, cioe` gli dice fai 8 bit per carattere.
      > Per default la fa lunga un'unita`, cioe` una parola della CPU, cioe` 32 bit qui.
      > E poi "per ogni P in un array di stringhe di bytes", fai la stessa cosa con P.
      > Pausa e poi chiudi il programma.
      > L'output e` ovviamente "Hello Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune and maybe Pluto".
      > Ah, gli underscore nelle stringhe marcano gli spazi.
      > Dai che si capisce, dai, non mi puoi dire... no? come no? In lacrime

      Che ne pensano quelli di ANOwhere?
      • Avatar
        ☺
        Scritto da
        altg
        utente che non utiene
        il 2014-10-29 21:29:06.0 alle 2014-10-29 21:29:06.0
        Trollate totali: 11540
        Re: Ci si capisce, vero?
        > Che ne pensano quelli di ANOwhere?

        Niente, a loro lo presento quando ho qualcosa di vagamente piu` completo e con un tutorial che abbraccia argomenti piu` interessanti della conversione di stringhe da 8 a 32 bit. A proposito, l'output del compilatore per quella routine:

        Immagine postata dall'utente

        dovrebbe evidenziare come il rapporto fra le istruzioni nel sorgente e quelle nell'output sia vicino a 1:1, insomma il fatto che fin qui non tradisce la sua natura di "assembly sotto un'altra forma". Poi c'e` a chi piacera` e a chi dira` che era meglio un CIL a stack machine invece di fare register naming a mano, ma a me mi piace cosi`. Imbarazzato
    • Avatar
      ☺
      Scritto da
      avvelentani
      Cubicolario
      il 2014-10-30 08:29:50.0 alle 2014-10-30 08:29:50.0
      Trollate totali: 18184
      Re: Ci si capisce, vero?
      non si capisce un cazzo.
      I think happiness is love
      - Vladimir Putin
      • Avatar
        ☺
        Scritto da
        altg
        utente che non utiene
        il 2014-10-30 10:41:52.0 alle 2014-10-30 10:41:52.0
        Trollate totali: 11540
        Re: Ci si capisce, vero?
        > non si capisce un cazzo.

        A bocca storta



        Um...

        Ottimo!
        E` quello che volevo, cosi` nessuno potra` fare casino col mio linguaggio. Ficoso
        • Avatar
          ☺
          Scritto da
          avvelentani
          Cubicolario
          il 2014-10-30 15:02:50.0 alle 2014-10-30 15:02:50.0
          Trollate totali: 18184
          Re: Ci si capisce, vero?
          Scritto da: altg
          > > non si capisce un cazzo.
          >
          > A bocca storta
          >
          >
          >
          > Um...
          >
          > Ottimo!
          > E` quello che volevo, cosi` nessuno potra` fare casino col mio linguaggio. Ficoso

          1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
          2. firstByte e` terminologia ambigua, si chiama most significant byte
          3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
          4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
          5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte, se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
          6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
          I think happiness is love
          - Vladimir Putin
          • Avatar
            ☺
            Scritto da
            altg
            utente che non utiene
            il 2014-10-31 17:14:06.0 alle 2014-10-31 17:14:06.0
            Trollate totali: 11540
            Re: Ci si capisce, vero?
            > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato

            Ci contavo: almeno quello aiutera` a familiarizzarsi.

            > 2. firstByte e` terminologia ambigua, si chiama most significant byte

            Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.

            > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)

            Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.

            > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine

            La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.

            > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,

            Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.

            > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)

            Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.

            > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?

            Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word, perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.

            Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
            • Avatar
              Scritto da
              Non Autenticato
              il 2014-10-31 17:21:21.0 alle 2014-10-31 17:21:21.0
              Re: Ci si capisce, vero?
              Scritto da: altg
              > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
              >
              > Ci contavo: almeno quello aiutera` a familiarizzarsi.
              >
              > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
              >
              > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
              >
              > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
              >
              > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
              >
              > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
              >
              > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
              >
              > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
              >
              > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
              >
              > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
              >
              > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
              >
              > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
              >
              > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word, perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
              >
              > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.

              un utilizzo efficientissimo della memoria fisica Rotola dal ridere
              • Avatar
                ☺
                Scritto da
                altg
                utente che non utiene
                il 2014-10-31 17:28:19.0 alle 2014-10-31 17:28:19.0
                Trollate totali: 11540
                Re: Ci si capisce, vero?
                > > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
                > >
                > > Ci contavo: almeno quello aiutera` a familiarizzarsi.
                > >
                > > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
                > >
                > > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
                > >
                > > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
                > >
                > > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
                > >
                > > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
                > >
                > > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
                > >
                > > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
                > >
                > > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
                > >
                > > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
                > >
                > > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
                > >
                > > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
                > >
                > > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word, perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
                > >
                > > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
                >
                > un utilizzo efficientissimo della memoria fisica Rotola dal ridere

                Filiolo, che pensi di doverci mantenere, in termini di testo non compresso o non codificato (cioe` su cui devi lavorare prontamente) nella memoria di lavoro? Il database di Wikipedia? Imbarazzato
                • Avatar
                  Scritto da
                  Non Autenticato
                  il 2014-10-31 17:44:20.0 alle 2014-10-31 17:44:20.0
                  Re: Ci si capisce, vero?
                  Scritto da: altg
                  > > > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
                  > > >
                  > > > Ci contavo: almeno quello aiutera` a familiarizzarsi.
                  > > >
                  > > > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
                  > > >
                  > > > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
                  > > >
                  > > > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
                  > > >
                  > > > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
                  > > >
                  > > > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
                  > > >
                  > > > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
                  > > >
                  > > > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
                  > > >
                  > > > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
                  > > >
                  > > > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
                  > > >
                  > > > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
                  > > >
                  > > > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
                  > > >
                  > > > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word, perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
                  > > >
                  > > > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
                  > >
                  > > un utilizzo efficientissimo della memoria fisica Rotola dal ridere
                  >
                  > Filiolo, che pensi di doverci mantenere, in termini di testo non compresso o non codificato (cioe` su cui devi lavorare prontamente) nella memoria di lavoro? Il database di Wikipedia? Imbarazzato

                  boh
                  • Avatar
                    ☺
                    Scritto da
                    altg
                    utente che non utiene
                    il 2014-10-31 17:50:49.0 alle 2014-10-31 17:50:49.0
                    Trollate totali: 11540
                    Re: Ci si capisce, vero?
                    > > > > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
                    > > > >
                    > > > > Ci contavo: almeno quello aiutera` a familiarizzarsi.
                    > > > >
                    > > > > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
                    > > > >
                    > > > > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
                    > > > >
                    > > > > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
                    > > > >
                    > > > > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
                    > > > >
                    > > > > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
                    > > > >
                    > > > > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
                    > > > >
                    > > > > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
                    > > > >
                    > > > > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
                    > > > >
                    > > > > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
                    > > > >
                    > > > > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
                    > > > >
                    > > > > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
                    > > > >
                    > > > > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word, perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
                    > > > >
                    > > > > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
                    > > >
                    > > > un utilizzo efficientissimo della memoria fisica Rotola dal ridere
                    > >
                    > > Filiolo, che pensi di doverci mantenere, in termini di testo non compresso o non codificato (cioe` su cui devi lavorare prontamente) nella memoria di lavoro? Il database di Wikipedia? Imbarazzato
                    >
                    > boh

                    Allora ricapitolo gentilmente io: quando fai lavorare il processore su del testo in memoria di lavoro in un compito che dev'essere efficiente, di solito non e` su una serie di 50 copie della divina commedia, ma su relativamente poche stringhe. Nel 99% dei casi non ha molta importanza come sono rappresentate in memoria, perche` se le stringhe sono massiccie vengono lasciate altrove, in memoria di massa o chi per lei, dove si puo` comunque scegliere la codifica piu` opportuna, inclusi vari algoritmi di compressione dal deflate in su. Dove conta il volume, il testo puo` tranquillamente prendere molto meno di 8 bit per carattere. In memoria, poco importa se ne prende 32 o 64.
            • Avatar
              ☺
              Scritto da
              avvelentani
              Cubicolario
              il 2014-10-31 20:30:06.0 alle 2014-10-31 20:30:06.0
              Trollate totali: 18184
              Re: Ci si capisce, vero?
              Scritto da: altg
              > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
              >
              > Ci contavo: almeno quello aiutera` a familiarizzarsi.
              >
              > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
              >
              > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.

              IMHO "first" e` comunque ambiguo, msb no.

              >
              > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
              >
              > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.

              Ma usare una cosa normale tipo * o [] o ?

              > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
              >
              > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.

              Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?

              >
              > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
              >
              > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.

              Con "ammazzano" intendevo che se lo fai ti becchi un SIGBUS, AFAIK in amd64 ottieni un degradamento delle prestazioni e basta. BTW in ARM esistono anche LDRB/LDRH/STRB/STRH.

              >
              > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
              >
              > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.

              Questo e` il modo in cui viene implemento da gcc:

                 0x000000000040054b <+43>:	mov    rdx,rsp
                 0x000000000040054e <+46>:	mov    ecx,DWORD PTR [rdx]
                 0x0000000000400550 <+48>:	add    rdx,0x4
                 0x0000000000400554 <+52>:	lea    eax,[rcx-0x1010101]
                 0x000000000040055a <+58>:	not    ecx
                 0x000000000040055c <+60>:	and    eax,ecx
                 0x000000000040055e <+62>:	and    eax,0x80808080
                 0x0000000000400563 <+67>:	je     0x40054e <main+46>
                 0x0000000000400565 <+69>:	mov    ecx,eax
                 0x0000000000400567 <+71>:	mov    esi,0x400734
                 0x000000000040056c <+76>:	mov    edi,0x1
                 0x0000000000400571 <+81>:	shr    ecx,0x10
                 0x0000000000400574 <+84>:	test   eax,0x8080
                 0x0000000000400579 <+89>:	cmove  eax,ecx
                 0x000000000040057c <+92>:	lea    rcx,[rdx+0x2]
                 0x0000000000400580 <+96>:	cmove  rdx,rcx
                 0x0000000000400584 <+100>:	add    al,al
                 0x0000000000400586 <+102>:	sbb    rdx,0x3
                 0x000000000040058a <+106>:	xor    eax,eax
                 0x000000000040058c <+108>:	sub    rdx,rbx
              


              a occhio mi sembra parecchio piu` efficiente.

              >
              > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
              >
              > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word,

              I processori sono anche piu` veloci a manipolare cose che stanno nella cache e moltiplicare per 4 la dimensione di tutte le stringhe non aiuta.

              > perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
              >
              > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.

              Mi sembra una follia.
              I think happiness is love
              - Vladimir Putin
              • Avatar
                Scritto da
                Non Autenticato
                il 2014-10-31 20:39:12.0 alle 2014-10-31 20:39:12.0
                Re: Ci si capisce, vero?
                Scritto da: avvelentani
                > Scritto da: altg
                > > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
                > >
                > > Ci contavo: almeno quello aiutera` a familiarizzarsi.
                > >
                > > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
                > >
                > > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
                >
                > IMHO "first" e` comunque ambiguo, msb no.

                Propongo MSByte Geek

                > > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
                > >
                > > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
                >
                > Ma usare una cosa normale tipo * o [] o ?

                Facciamo * O [] o così mi ricorda i loghi di gengiva.

                > > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
                > >
                > > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
                >
                > Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?
                >
                > >
                > > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
                > >
                > > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
                >
                > Con "ammazzano" intendevo che se lo fai ti becchi un SIGBUS, AFAIK in amd64 ottieni un degradamento delle prestazioni e basta. BTW in ARM esistono anche LDRB/LDRH/STRB/STRH.
                >
                > >
                > > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
                > >
                > > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
                >
                > Questo e` il modo in cui viene implemento da gcc:
                >
                >
                > 0x000000000040054b <+43>:	mov    rdx,rsp
                > 0x000000000040054e <+46>:	mov    ecx,DWORD PTR [rdx]
                > 0x0000000000400550 <+48>:	add    rdx,0x4
                > 0x0000000000400554 <+52>:	lea    eax,[rcx-0x1010101]
                > 0x000000000040055a <+58>:	not    ecx
                > 0x000000000040055c <+60>:	and    eax,ecx
                > 0x000000000040055e <+62>:	and    eax,0x80808080
                > 0x0000000000400563 <+67>:	je     0x40054e <main+46>
                > 0x0000000000400565 <+69>:	mov    ecx,eax
                > 0x0000000000400567 <+71>:	mov    esi,0x400734
                > 0x000000000040056c <+76>:	mov    edi,0x1
                > 0x0000000000400571 <+81>:	shr    ecx,0x10
                > 0x0000000000400574 <+84>:	test   eax,0x8080
                > 0x0000000000400579 <+89>:	cmove  eax,ecx
                > 0x000000000040057c <+92>:	lea    rcx,[rdx+0x2]
                > 0x0000000000400580 <+96>:	cmove  rdx,rcx
                > 0x0000000000400584 <+100>:	add    al,al
                > 0x0000000000400586 <+102>:	sbb    rdx,0x3
                > 0x000000000040058a <+106>:	xor    eax,eax
                > 0x000000000040058c <+108>:	sub    rdx,rbx
                > 

                >
                > a occhio mi sembra parecchio piu` efficiente.
                >
                > >
                > > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
                > >
                > > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word,
                >
                > I processori sono anche piu` veloci a manipolare cose che stanno nella cache e moltiplicare per 4 la dimensione di tutte le stringhe non aiuta.
                >
                > > perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
                > >
                > > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
                >
                > Mi sembra una follia.
              • Avatar
                ☺
                Scritto da
                altg
                utente che non utiene
                il 2014-10-31 21:54:17.0 alle 2014-10-31 21:54:17.0
                Trollate totali: 11540
                Re: Ci si capisce, vero?
                > > > 1. per capire (vagamente) cosa cazzo stai facendo ho dovuto leggere l'output del disassembler che hai postato
                > >
                > > Ci contavo: almeno quello aiutera` a familiarizzarsi.
                > >
                > > > 2. firstByte e` terminologia ambigua, si chiama most significant byte
                > >
                > > Qui si chiama first perche` non c'e` ambiguita` dovuta all'endianness. L'endianness della memoria di lavoro e` sempre big: quello piu` a sinistra e` il primo, poi c'e` il secondo, il terzo, il quarto e, sui processori a 64 bit, quinto sesto settimo e ottavo. Quindi non e` ambiguo definirlo in termini posizionali.
                >
                > IMHO "first" e` comunque ambiguo, msb no.

                IMHO pero` msb e` meno comprensibile. Poi per carita`, mi va bene anche MSB e probabilmente nelle istruzioni avro` l'occasione di precisare che e` quello. Tanto piu` che non avremo neanche ambiguita` come l'LSD (Least Significant Doubleword). A bocca aperta

                > > > 3. mi pare di capire che se usi il nome di un registro con la lettera maiuscola lo dereferenzi --> Ranonail (tra l'altro chi e` che setta EDI/w?)
                > >
                > > Esatto, anche se io la chiamo piu` tradizionalmente indirezione. Dereferenziare e` un termine connesso al C. L'indirezione con spiazzamento zero e` marcata sinteticamente dalla lettera maiuscola.
                >
                > Ma usare una cosa normale tipo * o [] o ?

                Lo facevo, lo feci, lo facetti, ne feci le veci. In L.in.oleum 1, si scriveva b per intendere il registro b, e [b] per intendere il contenuto della locazione puntata da b. Ma la gente si confondeva lo stesso, in compenso tutte quelle quadre mi davano sui nervi perche` non potevo scrivere [b] in un carattere solo e mi si disallineavano le istruzioni. Io ho la paturnia degli allineamenti. Imbarazzato

                Comunque mi piace il nuovo schema:
                - p significa il registro p
                - P significa [p], indiretto con base p e spiazzamento zero
                - p.1 significa [p+1]
                - p.-1 significa [p-1]
                - p.1.1 significa [p+1+1] cioe` [p+2]
                - eccetera...

                > > > 4. se la stringa di input non fosse 4-allineata (e non vedo per quale motivo una stringa di byte dovrebbe esserlo) non solo ti fai una marea di accessi disallineati (che ammazzerebbero, ad esempio, un ARM) ma potrebbe anche causare un segfault alla fine
                > >
                > > La stringa di input e` per forza allineata a una boundary di 4 byte, ovvero di un'unita` per come la definisce L.in.oleum (per distinguerla dal significato tradizionalmente confuso di "word"). L'allineamento e` dovuto al fatto che L.in.oleum in nessun punto permette accessi disallineati (in effetti andrebbe a nozze con gli ARM). Semplicemente non conosce i byte: i byte sono parti interne delle unita`.
                >
                > Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?

                Be', se ci sono sequenze non allineate e vengono lette una volta sola, non ci sarebbe altro modo che contorcersi un po'. Riconosco che e` uno svantaggio, ma del resto indirizzare la memoria in unita` piuttosto che in bytes ha molti altri vantaggi.

                > > > 5. non capisco perche' il codice sia scritto in modo da essere non-efficiente e non-leggibile, se fosse leggibile l'accesso sarebbe fatto byte per byte,
                > >
                > > Non puoi, altrimenti hai i disallineamenti e problemi di endianness di cui sopra. L.in.oleum sacrifica l'accesso byte per byte per evitare questo genere di problemi, che lo renderebbero irrimediabilmente non portabile (se cambiasse la endianness il sorgente sarebbe da buttare). E poi gli accessi disallineati non ammazzano solo gli ARM, ammazzano anche gli Intel superscalari dal Pentium in poi, che ormai sono CISC di nome, ma di fatto funzionano meglio se li si usa in modo molto simile a un RISC.
                >
                > Con "ammazzano" intendevo che se lo fai ti becchi un SIGBUS, AFAIK in amd64 ottieni un degradamento delle prestazioni e basta. BTW in ARM esistono anche LDRB/LDRH/STRB/STRH.

                Poi dici che non t'interessa l'assembly. A bocca storta

                > > > se fosse efficiente il loop con gli shift sulla maschera sarebbe parzialmente srotolato (e a naso mi sa che ci sono modi piu` efficienti di manipolare stringhe su x86)
                > >
                > > Intrinsecamente piu` efficienti, penso di no. Se stai pensando a cazzate come rep scasb stai pensando a roba dei tempi del 386, gia` il 486 avrebbe arrancato meno con cicli estesi. Per lo srotolamento, rendo atto che sarebbe un po' piu` efficiente, ma considera che le librerie di quel gruppo sono ottimizzate piu` per compattezza che per velocita`.
                >
                > Questo e` il modo in cui viene implemento da gcc:
                >
                >
                > 0x000000000040054b <+43>:	mov    rdx,rsp
                > 0x000000000040054e <+46>:	mov    ecx,DWORD PTR [rdx]
                > 0x0000000000400550 <+48>:	add    rdx,0x4
                > 0x0000000000400554 <+52>:	lea    eax,[rcx-0x1010101]
                > 0x000000000040055a <+58>:	not    ecx
                > 0x000000000040055c <+60>:	and    eax,ecx
                > 0x000000000040055e <+62>:	and    eax,0x80808080
                > 0x0000000000400563 <+67>:	je     0x40054e <main+46>
                > 0x0000000000400565 <+69>:	mov    ecx,eax
                > 0x0000000000400567 <+71>:	mov    esi,0x400734
                > 0x000000000040056c <+76>:	mov    edi,0x1
                > 0x0000000000400571 <+81>:	shr    ecx,0x10
                > 0x0000000000400574 <+84>:	test   eax,0x8080
                > 0x0000000000400579 <+89>:	cmove  eax,ecx
                > 0x000000000040057c <+92>:	lea    rcx,[rdx+0x2]
                > 0x0000000000400580 <+96>:	cmove  rdx,rcx
                > 0x0000000000400584 <+100>:	add    al,al
                > 0x0000000000400586 <+102>:	sbb    rdx,0x3
                > 0x000000000040058a <+106>:	xor    eax,eax
                > 0x000000000040058c <+108>:	sub    rdx,rbx
                > 

                >
                > a occhio mi sembra parecchio piu` efficiente.

                A occhio non ci ho capito una minchia. Perplesso

                La prima sequenza fino al "je", esclusa la prima istruzione, e` un ciclo che rileva byte posti a zero in un buffer che comincia a rsp (suppongo sia qualcosa di locale sullo stack), poi c'e` qualcos'altro che include delle mov predicate ma che mi sembra incompleto: da nessuna parte si direbbero presenti delle istruzioni di write-back. Legge soltanto? Si puo` avere il sorgente che ha prodotto quel frammento?

                > > > 6. per quale motivo i caratteri delle tue stringhe sono di 32bit quando non supporti unicode? Anche se in un futuro dovessi supportare unicode, per quale motivo scegliere l'encoding massimamente inefficiente come default?
                > >
                > > Perche` i processori sono piu` veloci nel manipolare dati di dimensione pari alla loro word,
                >
                > I processori sono anche piu` veloci a manipolare cose che stanno nella cache e moltiplicare per 4 la dimensione di tutte le stringhe non aiuta.

                Vero. A dirla tutta, per ora il fatto che il compilatore funzioni a passo singolo e non usi salti corti espande anche il codice riducendone la localita`, cosa che mi secca parecchio di piu` dei dati. Certo, sono svantaggi che posso tenere presenti, ma se non voglio inserire istruzioni che accedano ai singoli bytes, non ho alternative. Per il compilatore, prima o poi magari gli faro` fare un passo aggiuntivo per scorciare i salti.

                > > perche` essendo che L.in.oleum manipola bytes solo come parti di una word mantenerle in memoria a una unita` per carattere e` infinitamente piu` comodo ed efficiente, e perche` se le volessi codificare scriverei una routine apposita prima di scaricarle da qualche parte.
                > >
                > > Figurati che se fosse compilato su un processore a 64 bit, ogni carattere prenderebbe 64 bit, una specie di inesistente UCS-8. Ma non e` appunto un fatto di avere piu` code points, e` proprio un fatto di allineamento puro e semplice. Non esistono bytes in L.in.oleum, dai tempi della prima versione, ne` possono esistere.
                >
                > Mi sembra una follia.

                Per come la vedo io, e` l'idealizzare una macchina semplificata che indirizza, legge e scrive unita` discrete di dimensione piu` utile del singolo byte, ECCETTO nel caso di stringhe di testo grandi e di accesso frequente e casuale. Nel qual caso, pazienza: come diceva Ford Prefect, "si fottano le oche, non ci si puo` occupare di ogni dannata cosa". Imbarazzato
                • Avatar
                  ☺
                  Scritto da
                  avvelentani
                  Cubicolario
                  il 2014-11-01 08:02:55.0 alle 2014-11-01 08:02:55.0
                  Trollate totali: 18184
                  Re: Ci si capisce, vero?
                  Scritto da: altg
                  > Comunque mi piace il nuovo schema:
                  > - p significa il registro p
                  > - P significa [p], indiretto con base p e spiazzamento zero
                  > - p.1 significa [p+1]
                  > - p.-1 significa [p-1]
                  > - p.1.1 significa [p+1+1] cioe` [p+2]
                  > - eccetera...

                  Un capolavoro di inconsistenza.

                  > > Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?
                  >
                  > Be', se ci sono sequenze non allineate e vengono lette una volta sola, non ci sarebbe altro modo che contorcersi un po'. Riconosco che e` uno svantaggio, ma del resto indirizzare la memoria in unita` piuttosto che in bytes ha molti altri vantaggi.

                  usi "allineato" in modo non-standard, una stringa di byte e` allineata a qualunque indirizzo, un in16 e` allineato a qualunque indirizzo divisibile per 2, &c. Tutti questi vantaggi dell'indirizzare la memoria solo a multipli di 4 io non ce li vedo, il fatto che non io non conosca un assembly che ti obbliga a farlo e che il C allinei le strutture come le allinea mi suggerisce che questi supposti vantaggi non esistano.

                  > > Con "ammazzano" intendevo che se lo fai ti becchi un SIGBUS, AFAIK in amd64 ottieni un degradamento delle prestazioni e basta. BTW in ARM esistono anche LDRB/LDRH/STRB/STRH.
                  >
                  > Poi dici che non t'interessa l'assembly. A bocca storta

                  Le architetture rilevanti saranno si e no una decina, non c'e` bisogno di essere interessati per avere una vaga familiarita`.


                  > >
                  > > 0x000000000040054b <+43>:	mov    rdx,rsp
                  > > 0x000000000040054e <+46>:	mov    ecx,DWORD PTR [rdx]
                  > > 0x0000000000400550 <+48>:	add    rdx,0x4
                  > > 0x0000000000400554 <+52>:	lea    eax,[rcx-0x1010101]
                  > > 0x000000000040055a <+58>:	not    ecx
                  > > 0x000000000040055c <+60>:	and    eax,ecx
                  > > 0x000000000040055e <+62>:	and    eax,0x80808080
                  > > 0x0000000000400563 <+67>:	je     0x40054e <main+46>
                  > > 0x0000000000400565 <+69>:	mov    ecx,eax
                  > > 0x0000000000400567 <+71>:	mov    esi,0x400734
                  > > 0x000000000040056c <+76>:	mov    edi,0x1
                  > > 0x0000000000400571 <+81>:	shr    ecx,0x10
                  > > 0x0000000000400574 <+84>:	test   eax,0x8080
                  > > 0x0000000000400579 <+89>:	cmove  eax,ecx
                  > > 0x000000000040057c <+92>:	lea    rcx,[rdx+0x2]
                  > > 0x0000000000400580 <+96>:	cmove  rdx,rcx
                  > > 0x0000000000400584 <+100>:	add    al,al
                  > > 0x0000000000400586 <+102>:	sbb    rdx,0x3
                  > > 0x000000000040058a <+106>:	xor    eax,eax
                  > > 0x000000000040058c <+108>:	sub    rdx,rbx
                  > > 

                  > >
                  > > a occhio mi sembra parecchio piu` efficiente.
                  >
                  > A occhio non ci ho capito una minchia. Perplesso
                  >
                  > La prima sequenza fino al "je", esclusa la prima istruzione, e` un ciclo che rileva byte posti a zero in un buffer che comincia a rsp (suppongo sia qualcosa di locale sullo stack), poi c'e` qualcos'altro che include delle mov predicate ma che mi sembra incompleto: da nessuna parte si direbbero presenti delle istruzioni di write-back. Legge soltanto? Si puo` avere il sorgente che ha prodotto quel frammento?

                  Certo:

                  #include <stdio.h>
                  #include <string.h>
                  
                  int main(int argc, char *argv[]) {
                          int i;
                          char blah[256];
                          gets(blah);
                          i = strlen(blah);
                          printf("%d\n", i);
                          return 0;
                  }
                  


                  Rotola dal ridere

                  Il codice di strlen e` questo: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/lib...

                  Il loop e` una ricerca per il primo int32 contenente un byte a 0.
                  La seconda parte e` un po' intricata ma con un po' di pazienza si capisce:
                  - edx e` l'indirizzo del primo int32 dopo il primo int32 contenente un byte a 0 nella stringa
                  - ebx contiene l'indirizzo della stringa (come anche rsp)
                  - le istruzioni main+71, main+76 e main+116 sono irrilevanti, servono per configurare printf
                  - il test a main+84 e le due successive cmove serve a decidere se il primo byte a 0 sta nei primi 2 byte o negli ultimi 2 byte
                  - l'istruzione main+102 e` dove edx viene aggiustato per puntare esattamente all'ultimo byte
                  - l'istruzione main+108 e` dove edx diventa la lunghezza della stringa.



                  >
                  > Vero. A dirla tutta, per ora il fatto che il compilatore funzioni a passo singolo e non usi salti corti espande anche il codice riducendone la localita`, cosa che mi secca parecchio di piu` dei dati. Certo, sono svantaggi che posso tenere presenti, ma se non voglio inserire istruzioni che accedano ai singoli bytes, non ho alternative. Per il compilatore, prima o poi magari gli faro` fare un passo aggiuntivo per scorciare i salti.

                  Quindi secondo te il fatto che le istruzioni di jump siano piu` lunghe di qualche byte rispetto a quanto potrebbero essere e` piu` importante del fatto che tutte le stringhe siano 4 volte piu` lunghe di quanto potrebbero essere?

                  I think happiness is love
                  - Vladimir Putin
                  • Avatar
                    ☺
                    Scritto da
                    altg
                    utente che non utiene
                    il 2014-11-01 13:06:53.0 alle 2014-11-01 13:06:53.0
                    Trollate totali: 11540
                    Re: Ci si capisce, vero?
                    > > Comunque mi piace il nuovo schema:
                    > > - p significa il registro p
                    > > - P significa [p], indiretto con base p e spiazzamento zero
                    > > - p.1 significa [p+1]
                    > > - p.-1 significa [p-1]
                    > > - p.1.1 significa [p+1+1] cioe` [p+2]
                    > > - eccetera...
                    >
                    > Un capolavoro di inconsistenza.

                    Perche` la vedi come un'espressione in generale: e` un'indirezione ed e` composta da un registro e un'espressione il cui valore e` lo spiazzamento. In altre parole, non avrebbe senso scrivere:

                    p/5+1

                    Il punto serve a separare due cose diverse e secondo me rende piu` chiaro cosa si puo` scrivere dall'una e dall'altra parte, cosi` come la darebbe un registro fuori dalle quadre nella sintassi intel:

                    edx [1+1]

                    Comunque potrebbe non essere una cattiva idea quella di ricondurla a un'espressione normale, per poi emettere un errore se l'operatore che segue un registro non e` compatibile con un'indirezione, cioe` permettere p+1 ma lamentarsi per p/5. Che ne dici?

                    > > > Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?
                    > >
                    > > Be', se ci sono sequenze non allineate e vengono lette una volta sola, non ci sarebbe altro modo che contorcersi un po'. Riconosco che e` uno svantaggio, ma del resto indirizzare la memoria in unita` piuttosto che in bytes ha molti altri vantaggi.
                    >
                    > usi "allineato" in modo non-standard, una stringa di byte e` allineata a qualunque indirizzo, un in16 e` allineato a qualunque indirizzo divisibile per 2, &c.

                    Parlando di come funziona L.in.oleum, presuppongo che "allineato" significhi a una parola del processore.

                    > Tutti questi vantaggi dell'indirizzare la memoria solo a multipli di 4 io non ce li vedo, il fatto che non io non conosca un assembly che ti obbliga a farlo e che il C allinei le strutture come le allinea mi suggerisce che questi supposti vantaggi non esistano.

                    Intanto il codice che hai postato legge 4 bytes (una "unita`") per volta e "si contorce" per estrarre dal valore composto di 4 byte il primo byte a zero? Se come dicevi "dovesse essere leggibile", leggerebbe byte per byte. ARM era stata pensata per avere tutte istruzioni di una word (32 bit) per semplificare la decodifica e il fetching. IA-32 mantiene le istruzioni storiche come lodsb/scasb/stosb solo per retrocompatibilita`, ma non le definirebbe mai efficienti. Il C preferisce essere comodo e non introdurre una scelta radicale come fa L.in.oleum, ma un vettore di dati non allineati a words del processore e` comunque piu` complicato e inefficiente da gestire, e lo obbliga a contorcersi.

                    > > > Con "ammazzano" intendevo che se lo fai ti becchi un SIGBUS, AFAIK in amd64 ottieni un degradamento delle prestazioni e basta. BTW in ARM esistono anche LDRB/LDRH/STRB/STRH.
                    > >
                    > > Poi dici che non t'interessa l'assembly. A bocca storta
                    >
                    > Le architetture rilevanti saranno si e no una decina, non c'e` bisogno di essere interessati per avere una vaga familiarita`.

                    Ti vergogni, sei un timidone! Imbarazzato

                    > > La prima sequenza fino al "je", esclusa la prima istruzione, e` un ciclo che rileva byte posti a zero in un buffer che comincia a rsp (suppongo sia qualcosa di locale sullo stack), poi c'e` qualcos'altro che include delle mov predicate ma che mi sembra incompleto: da nessuna parte si direbbero presenti delle istruzioni di write-back. Legge soltanto? Si puo` avere il sorgente che ha prodotto quel frammento?
                    >
                    > Certo:
                    >
                    >
                    > #include <stdio.h>
                    > #include <string.h>
                    > 
                    > int main(int argc, char *argv[]) {
                    > int i;
                    > char blah[256];
                    > gets(blah);
                    > i = strlen(blah);
                    > printf("%d\n", i);
                    > return 0;
                    > }
                    > 

                    >
                    > Rotola dal ridere

                    Pff... pensavo tu avessi voluto postare un equivalente dell'intera routine di conversione da 8 a 32 bit per carattere. Ok, il ciclo che cercava la lunghezza della stringa l'avevo identificato e immagino fosse a quello che ti riferivi, ma e` l'unica parte in comune col codice L.in.oleum di cui si parlava.

                    > Il codice di strlen e` questo: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/lib...
                    >
                    > Il loop e` una ricerca per il primo int32 contenente un byte a 0.
                    > La seconda parte e` un po' intricata ma con un po' di pazienza si capisce:
                    > - edx e` l'indirizzo del primo int32 dopo il primo int32 contenente un byte a 0 nella stringa
                    > - ebx contiene l'indirizzo della stringa (come anche rsp)
                    > - le istruzioni main+71, main+76 e main+116 sono irrilevanti, servono per configurare printf
                    > - il test a main+84 e le due successive cmove serve a decidere se il primo byte a 0 sta nei primi 2 byte o negli ultimi 2 byte
                    > - l'istruzione main+102 e` dove edx viene aggiustato per puntare esattamente all'ultimo byte
                    > - l'istruzione main+108 e` dove edx diventa la lunghezza della stringa.

                    Come vedi, si "contorce", legge words di 4 byte intere, e non byte per byte, e in effetti replica letture di 4 byte per volta. Ora posso farti vedere la ricerca della lunghezza di una stringa di 32 bit per carattere in L.in.oleum?

                    00000273 89F2                MOV.rm,r        EDX(p), ESI(r)
                    00000275 833CB700            CMP.rm,i        [EDI(w)+4*ESI(r)], 00
                    00000279 0F840E000000        JE              0000000E ; 0000028D
                    0000027F 837CB70400          CMP.rm,i        [EDI(w)+4*ESI(r)+04], 00
                    00000284 8D7601              LEA.r,m         ESI(r), [ESI(r)+1]
                    00000287 0F85F2FFFFFF        JNE             FFFFFFF2 ; 0000027F
                    0000028D 29D6                SUB.rm,r        ESI(r), EDX(p)
                    


                    Le istruzioni nel sorgente sono:

                    p = r
                    each R
                    r - p
                    


                    In pratica, copia l'indirizzo della stringa (r) in p.
                    Poi fa un ciclo "each" vuoto, che va avanti per ogni R non zero.
                    Infine, sottrae p ad r per trovare la differenza, che e` la lunghezza.
                    Il ciclo vero e proprio, tolto il caso della stringa vuota, e`:

                    0000027F 837CB70400          CMP.rm,i        [EDI(w)+4*ESI(r)+04], 00
                    00000284 8D7601              LEA.r,m         ESI(r), [ESI(r)+1]
                    00000287 0F85F2FFFFFF        JNE             FFFFFFF2 ; 0000027F
                    


                    tre istruzioni in croce. Ok, ci saranno i ritardi di cache 4 volte piu` spesso che se la stringa fosse fatta di bytes, ma immagina come sarebbe piu` facile trattare i caratteri di una stringa in questo modo, manipolarli e trasformarli. A partire dal cercarne la lunghezza senza contorsioni.

                    > Quindi secondo te il fatto che le istruzioni di jump siano piu` lunghe di qualche byte rispetto a quanto potrebbero essere e` piu` importante del fatto che tutte le stringhe siano 4 volte piu` lunghe di quanto potrebbero essere?

                    La localita` del codice e` almeno altrettanto importante, ma probabilmente di piu`: quella si applica a tutto il codice, le stringhe di testo a 8 bit sono casi particolari. E` un difetto del compilatore abbozzato attuale, ma mi prometto di risolverlo in seguito.
                    • Avatar
                      ☺
                      Scritto da
                      avvelentani
                      Cubicolario
                      il 2014-11-02 09:16:47.0 alle 2014-11-02 09:16:47.0
                      Trollate totali: 18184
                      Re: Ci si capisce, vero?
                      Scritto da: altg
                      > > > Comunque mi piace il nuovo schema:
                      > > > - p significa il registro p
                      > > > - P significa [p], indiretto con base p e spiazzamento zero
                      > > > - p.1 significa [p+1]
                      > > > - p.-1 significa [p-1]
                      > > > - p.1.1 significa [p+1+1] cioe` [p+2]
                      > > > - eccetera...
                      > >
                      > > Un capolavoro di inconsistenza.
                      >
                      > Perche` la vedi come un'espressione in generale: e` un'indirezione ed e` composta da un registro e un'espressione il cui valore e` lo spiazzamento. In altre parole, non avrebbe senso scrivere:
                      >
                      > p/5+1
                      >
                      > Il punto serve a separare due cose diverse e secondo me rende piu` chiaro cosa si puo` scrivere dall'una e dall'altra parte, cosi` come la darebbe un registro fuori dalle quadre nella sintassi intel:
                      >
                      > edx [1+1]
                      >
                      > Comunque potrebbe non essere una cattiva idea quella di ricondurla a un'espressione normale, per poi emettere un errore se l'operatore che segue un registro non e` compatibile con un'indirezione, cioe` permettere p+1 ma lamentarsi per p/5. Che ne dici?

                      Dico che sarebbe meglio visto che la sintassi intel funziona cosi` da sempre. Ci metterei anche delle parentesi quadre attorno.

                      >
                      > > > > Quindi se uno volesse accedere ad un file mmappato ti ci devi contorcere attorno?
                      > > >
                      > > > Be', se ci sono sequenze non allineate e vengono lette una volta sola, non ci sarebbe altro modo che contorcersi un po'. Riconosco che e` uno svantaggio, ma del resto indirizzare la memoria in unita` piuttosto che in bytes ha molti altri vantaggi.
                      > >
                      > > usi "allineato" in modo non-standard, una stringa di byte e` allineata a qualunque indirizzo, un in16 e` allineato a qualunque indirizzo divisibile per 2, &c.
                      >
                      > Parlando di come funziona L.in.oleum, presuppongo che "allineato" significhi a una parola del processore.

                      Allineato nel mondo normale significa che l'indirizzo e` un multiplo della dimensione.

                      >
                      > > Tutti questi vantaggi dell'indirizzare la memoria solo a multipli di 4 io non ce li vedo, il fatto che non io non conosca un assembly che ti obbliga a farlo e che il C allinei le strutture come le allinea mi suggerisce che questi supposti vantaggi non esistano.
                      >
                      > Intanto il codice che hai postato legge 4 bytes (una "unita`") per volta e "si contorce" per estrarre dal valore composto di 4 byte il primo byte a zero? Se come dicevi "dovesse essere leggibile", leggerebbe byte per byte.

                      Il codice che ho postato io non e` fatto per essere leggibile, e` fatto per essere veloce. E non e` solo per via dell'allineamento ma anche perche' e` bit-parallelo. Se dopo aver fatto il tuo bel load allineato ti devi andare a pescare i singoli byte a botte di shr e and e` molto piu` veloce e leggibile fare una lettura non allineata.

                      > ARM era stata pensata per avere tutte istruzioni di una word (32 bit) per semplificare la decodifica e il fetching.

                      http://infocenter.arm.com/help/index.jsp?topic=/co...

                      LDRB e SDRB ci sono sempre stati.

                      > tre istruzioni in croce. Ok, ci saranno i ritardi di cache 4 volte piu` spesso che se la stringa fosse fatta di bytes,

                      Hai detto niente!

                      > > Quindi secondo te il fatto che le istruzioni di jump siano piu` lunghe di qualche byte rispetto a quanto potrebbero essere e` piu` importante del fatto che tutte le stringhe siano 4 volte piu` lunghe di quanto potrebbero essere?
                      >
                      > La localita` del codice e` almeno altrettanto importante, ma probabilmente di piu`: quella si applica a tutto il codice, le stringhe di testo a 8 bit sono casi particolari. E` un difetto del compilatore abbozzato attuale, ma mi prometto di risolverlo in seguito.

                      Secondo te cosa prende piu` spazio? Il codice o i dati?
                      Secondo me a te piace il fatto che hai un solo tipo di dato perche' semplifica il tuo codice e lo giustifichi con l'efficienza ma e` solo una razionalizzazione a posteriori che scarti tutte le volte che non ti fa comodo per giustificare la tua semplificazione.
                      I think happiness is love
                      - Vladimir Putin
                      • Avatar
                        ☺
                        Scritto da
                        altg
                        utente che non utiene
                        il 2014-11-02 15:22:57.0 alle 2014-11-02 15:22:57.0
                        Trollate totali: 11540
                        Re: Ci si capisce, vero?
                        > Dico che sarebbe meglio visto che la sintassi intel funziona cosi` da sempre.

                        Va be', terro` presente, puo` darsi che cambi idea. La sintassi intel e` ben affermata, lo ammetto, pero` la trovo meno descrittiva di "p.-1" perche` assume che uno spiazzamento possa essere direttamente sottratto all'indirizzo di base, mentre in realta` e` aggiunto come valore negativo in complemento a due.

                        > Ci metterei anche delle parentesi quadre attorno.

                        Non mi conviene, le sto usando per definire array inline.
                        Cioe`:

                        x = [ 1, 2, 3 ]

                        carica "x" con l'indirizzo di un array statica contenente le words 1, 2, 3 (e poi zero, perche` per default e` null-terminated). Poi dovrei in qualche modo distinguere i casi.

                        > > Parlando di come funziona L.in.oleum, presuppongo che "allineato" significhi a una parola del processore.
                        >
                        > Allineato nel mondo normale significa che l'indirizzo e` un multiplo della dimensione.

                        Vabbe', se lo dici te... per me "allineato" senza "a cosa" era un errore di sintassi, al massimo sfruttabile per intendere "a una granularita` di default". A bocca storta

                        > > > Tutti questi vantaggi dell'indirizzare la memoria solo a multipli di 4 io non ce li vedo, il fatto che non io non conosca un assembly che ti obbliga a farlo e che il C allinei le strutture come le allinea mi suggerisce che questi supposti vantaggi non esistano.
                        > >
                        > > Intanto il codice che hai postato legge 4 bytes (una "unita`") per volta e "si contorce" per estrarre dal valore composto di 4 byte il primo byte a zero? Se come dicevi "dovesse essere leggibile", leggerebbe byte per byte.
                        >
                        > Il codice che ho postato io non e` fatto per essere leggibile, e` fatto per essere veloce. E non e` solo per via dell'allineamento ma anche perche' e` bit-parallelo.

                        Bit-che?
                        Legge 4 byte per volta, come fa la reimplementazione L.in.oleum.
                        E` parallelo tanto quanto lo e` la sua reimplementazione, qualunque cosa tu intendessi per bit-parallelo.
                        Non legge i singoli bytes per trovare il terminatore, processa intere words.

                        > Se dopo aver fatto il tuo bel load allineato ti devi andare a pescare i singoli byte a botte di shr e and e` molto piu` veloce e leggibile fare una lettura non allineata.

                        Leggibile magari si`, veloce no. In generale, se leggi un registro di 32 bit per operare sui bytes che contiene, fai un accesso parallelo di 4 bytes invece che seriale byte per byte.

                        mov eax, [esi]       ; 1
                        add esi, 4
                        mov ebx, eax         ; 1
                        mov ecx, eax
                        mov edx, eax         ; 1
                        and eax, 0xFF
                        and ebx, 0xFF00      ; 1
                        and ecx, 0xFF0000
                        and edx, 0xFF000000  ; 1
                        shr ebx, 8           ; 1
                        shr ecx, 16          ; 1
                        shr edx, 24          ; 1
                                             ; 8
                        


                        mov al, [esi]        ; 2
                        mov bl, [esi + 1]    ; 2
                        mov cl, [esi + 2]    ; 2
                        mov dl, [esi + 3]    ; 2
                        add esi, 4           ; 1
                                             ; 9
                        


                        Certo a meno che uno debba leggere un byte solo, ma a quel punto di solito non fai un ciclo.

                        > > ARM era stata pensata per avere tutte istruzioni di una word (32 bit) per semplificare la decodifica e il fetching.
                        >
                        > http://infocenter.arm.com/help/index.jsp?topic=/co...
                        >
                        > LDRB e SDRB ci sono sempre stati.

                        Chissa` se sono penalizzati.
                        Gli Intel penalizzano gli accessi non allineati alla word del processore.

                        > > tre istruzioni in croce. Ok, ci saranno i ritardi di cache 4 volte piu` spesso che se la stringa fosse fatta di bytes,
                        >
                        > Hai detto niente!

                        Ma non intendo dire che quando operi su stringhe di caratteri allineati a una word, lo fai perche` la stringa e` colossale. Le converti a stringhe del genere quando devi manipolare frequentemente la stessa stringa, tipo splittarla o concatenarne frammenti. In generale, stai immaginando casi che secondo me sono molto rari, dove la performance dovuta alla specifica capacita` di leggere singoli bytes farebbe la differenza.

                        > > > Quindi secondo te il fatto che le istruzioni di jump siano piu` lunghe di qualche byte rispetto a quanto potrebbero essere e` piu` importante del fatto che tutte le stringhe siano 4 volte piu` lunghe di quanto potrebbero essere?
                        > >
                        > > La localita` del codice e` almeno altrettanto importante, ma probabilmente di piu`: quella si applica a tutto il codice, le stringhe di testo a 8 bit sono casi particolari. E` un difetto del compilatore abbozzato attuale, ma mi prometto di risolverlo in seguito.
                        >
                        > Secondo te cosa prende piu` spazio? Il codice o i dati?

                        E secondo te cosa viene letto piu` spesso, il codice o i dati?

                        > Secondo me a te piace il fatto che hai un solo tipo di dato perche' semplifica il tuo codice

                        Non lo semplifica affatto, tant'e` che se devo gestire bytes singoli mi tocca contorcermi. Certo, l'espansione a 32 bit delle stringhe a quel punto lo semplifica, ma probabilmente non ho chiarito bene che si tratta di casi in cui si sa che le stringhe sono relativamente piccole e che vanno manipolate spesso. Una sorta di processo di "importazione" di una stringa a n bit nel "mondo a words" di L.in.oleum.

                        > e lo giustifichi con l'efficienza ma e` solo una razionalizzazione a posteriori che scarti tutte le volte che non ti fa comodo per giustificare la tua semplificazione.

                        Senz'altro mi piace l'idea di avere un solo tipo di dato, si`, ma ha dei vantaggi nelle manipolazioni frequenti di stringhe brevi, e d'altra parte secondo me tu stai ingigantendo il caso delle stringhe ASCII/UTF8 di lunghezza rilevante, che sono praticamente l'unico tipo di dato che verrebbe penalizzato dalla loro espansione e che spesso non dovrebbe essere espanso in primo luogo, a meno di processarle in maniera complessa (come in un text editor, ad esempio).

                        Per il resto, chiarisco che nessuno impedisce di tenerle in bytes e andarci di operazioni binarie su word intere: non mi stupirei se come per strlen di glib, probabilmente anche chi puo` leggere singoli bytes preferisca gestire words intere nei cicli. Ti faccio notare che la strlen che hai postato e` praticamente una smentita dei vantaggi dell'accesso byte per byte: accede word per word per essere efficiente, parallelizzando il trattamento di 4 byte per volta.
                  • Avatar
                    ☺
                    Scritto da
                    altg
                    utente che non utiene
                    il 2014-11-01 13:37:09.0 alle 2014-11-01 13:37:09.0
                    Trollate totali: 11540
                    Re: Ci si capisce, vero?
                    > Il codice di strlen e` questo: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/lib...

                    p.s. comunque la tattica per trovare il terminatore confrontando 4 byte per volta e` carina, non la sapevo e ora la importo in text::FromByteString. Intanto, pero`, volevo farti notare che L.in.oleum, allineando tutto a word del processore, nel fare la stessa cosa per poter sfruttare confronti su 4 byte per volta, puo` saltare questo:

                      /* Handle the first few characters by reading one character at a time.
                         Do this until CHAR_PTR is aligned on a longword boundary.  */
                      for (char_ptr = str; ((unsigned long int) char_ptr
                    			& (sizeof (longword) - 1)) != 0;
                           ++char_ptr)
                        if (*char_ptr == '\0')
                          return char_ptr - str;
                    


                    Sei ancora convinto che tutti questi vantaggi non ci siano?
                    • Avatar
                      ☺
                      Scritto da
                      altg
                      utente che non utiene
                      il 2014-11-01 15:17:58.0 alle 2014-11-01 15:17:58.0
                      Trollate totali: 11540
                      Re: Ci si capisce, vero?
                      > > Il codice di strlen e` questo: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/lib...
                      >
                      > p.s. comunque la tattica per trovare il terminatore confrontando 4 byte per volta e` carina, non la sapevo e ora la importo in text::FromByteString. Intanto, pero`, volevo farti notare che L.in.oleum, allineando tutto a word del processore, nel fare la stessa cosa per poter sfruttare confronti su 4 byte per volta, puo` saltare questo:
                      >
                      >
                      > /* Handle the first few characters by reading one character at a time.
                      > Do this until CHAR_PTR is aligned on a longword boundary.  */
                      > for (char_ptr = str; ((unsigned long int) char_ptr
                      > 			& (sizeof (longword) - 1)) != 0;
                      > ++char_ptr)
                      > if (*char_ptr == '\0')
                      > return char_ptr - str;
                      > 

                      >
                      > Sei ancora convinto che tutti questi vantaggi non ci siano?

                      Ho reimplementato in L.in.oleum il ciclo word-per-word visto nella strlen di GCC: e` senz'altro un'ottima idea, per quanto renda il codice praticamente incomprensibile (per rendermi conto di cosa vagamente facesse, ieri sera, ci ho messo un quarto d'ora, per poi non capire come il resto dovesse convertire una stringa da 8 a 32 bit per carattere).

                      Ma vediamo il filmaggine sull'analisi di quanto efficiente sia il codice prodotto dal compilatore C versus quello ottimizzato a mente (seguendo regole di ottimizzazione multiscalare piuttosto generiche) da un opportuno hikikomori...

                                                                      ByteString Length "monaural fn
                      
                      PUSH.r          ECX(m)                                  --> m
                      PUSH.r          EAX(n)                                  --> n
                      PUSH.r          EDX(p)                                  --> p = r
                      MOV.rm,r        EDX(p), ESI(r)
                      LOOP ENTRY                                              do
                      MOV.r,rm        EAX(n), [EDI(w)+4*ESI(r)]                   n = R
                      MOV.r,rm        ECX(m), [EDI(w)+4*ESI(r)]                   m = R
                      SUB.ac,i        EAX, 01010101                               n - 01010101h
                      NOT.rm          ECX(m)                                      ! m
                      AND.rm,r        EAX(n), ECX(m)                              n & m
                      ADD.rm,i        ESI(r), 01                                  r + 1
                      TEST.ac,i       EAX, 80808080                               continue if n has no 80808080h
                      JZ              00000000 ; 00000277 (TBD)
                      AND.ac,i        EAX, 80808080                               n & 80808080h
                      LOOP EXIT                                               end do (auto)
                      SUB.rm,i        ESI(r), 01                              r - 1
                      SUB.rm,r        ESI(r), EDX(p)                          r - p
                      SHL.rm,i        ESI(r), 02                              r < log2 bytesPerUnit
                      TEST.ac,i       EAX, FF000000                           repeat if n has no firstByte
                      JNZ             00000000 ; fwrd
                      ROL.rm,i        EAX(n), 08                                  n [ 8
                      ADD.rm,i        ESI(r), 01                                  r + 1
                      TEST.ac,i       EAX, FF000000                           end repeat if (auto)
                      JZ              00000000 ; 000002AC (TBD)
                      POP.r           EDX(p)                                  <-- p
                      POP.r           EAX(n)                                  <-- n
                      POP.r           ECX(m)                                  <-- m
                      RET.near                                                return
                      
                      ---------------------------------------------------------------------------------------------------
                      
                      MOV.r,rm        EAX(n), [EDI(w)+4*ESI(r)]               1       U
                      MOV.r,rm        ECX(m), [EDI(w)+4*ESI(r)]               0       V (ovviamente cached)
                      SUB.ac,i        EAX, 01010101                           1       U
                      NOT.rm          ECX(m)                                  0       V
                      AND.rm,r        EAX(n), ECX(m)                          1       U
                      ADD.rm,i        ESI(r), 01                              0       V
                      TEST.ac,i       EAX, 80808080                           1       U
                      JZ              00000000 ; 00000277 (TBD)               0       V (se predicted)
                                                                             ---
                                                                              4       cicli/word
                      
                      ---------------------------------------------------------------------------------------------------
                      
                      0x000000000040054e <+46>:	mov    ecx,DWORD PTR [rdx]    1       U
                      0x0000000000400550 <+48>:	add    rdx,0x4                0       V
                      0x0000000000400554 <+52>:	lea    eax,[rcx-0x1010101]    2       U (AGI* su RCX)
                      0x000000000040055a <+58>:	not    ecx                    0       V
                      0x000000000040055c <+60>:	and    eax,ecx                1       U
                      0x000000000040055e <+62>:	and    eax,0x80808080         1       V (write after write su EAX)
                      0x0000000000400563 <+67>:	je     0x40054e <main+46>     1       U (la pipe U non ha prediction)
                                                                             ---
                                                                              6       cicli/word
                      
                      *Address Generation Interlock, stallo della pipeline dovuto all'uso di LEA per fare MOV+SUB
                      


                      In conclusione, il codice C compilato e` efficiente nella scelta dell'algoritmo, che sicuramente e` piu` veloce che iterare su ogni byte (quello che i commenti di strlen definiscono "tradizionale"), ed e` una bella ottimizzazione fatta A MENTE da chi ha scritto quella versione di strlen. Il compilatore, pero`, a parte un'ottima strength reduction sulle righe successive, nel ciclo si caga abbastanza addosso. Buona serata.
                      • Avatar
                        Scritto da
                        Non Autenticato
                        il 2014-11-01 18:40:17.0 alle 2014-11-01 18:40:17.0
                        Re: Ci si capisce, vero?
                        > Buona serata.

                        Meno male che c'è sassofono: magari fra le sue critiche salta anche fuori qualcosa di utile.
                        • Avatar
                          ☺
                          Scritto da
                          altg
                          utente che non utiene
                          il 2014-11-01 20:15:17.0 alle 2014-11-01 20:15:17.0
                          Trollate totali: 11540
                          Re: Ci si capisce, vero?
                          > > Buona serata.
                          >
                          > Meno male che c'è sassofono: magari fra le sue critiche salta anche fuori qualcosa di utile.

                          Sshhh... e` per quello che posto la roba ogni tanto.
                          Ma se glielo dici e` abbastanza dispettoso da non cacarmela piu`. Fantasma
                          • Avatar
                            Scritto da
                            Non Autenticato
                            il 2014-11-01 20:28:08.0 alle 2014-11-01 20:28:08.0
                            Re: Ci si capisce, vero?
                            Scritto da: altg
                            > > > Buona serata.
                            > >
                            > > Meno male che c'è sassofono: magari fra le sue critiche salta anche fuori qualcosa di utile.
                            >
                            > Sshhh... e` per quello che posto la roba ogni tanto.
                            > Ma se glielo dici e` abbastanza dispettoso da non cacarmela piu`. Fantasma

                            ormai lo sa
                            • Avatar
                              Scritto da
                              Non Autenticato
                              il 2014-11-01 20:50:09.0 alle 2014-11-01 20:50:09.0
                              Re: Ci si capisce, vero?
                              Scritto da:
                              > Scritto da: altg
                              > > > > Buona serata.
                              > > >
                              > > > Meno male che c'è sassofono: magari fra le sue critiche salta anche fuori qualcosa di utile.
                              > >
                              > > Sshhh... e` per quello che posto la roba ogni tanto.
                              > > Ma se glielo dici e` abbastanza dispettoso da non cacarmela piu`. Fantasma
                              >
                              > ormai lo sa

                              Azz, dovevo star zitto. Triste
                              Comunque mi ammutolisce vedere quante cose sa sassofono.
                              • Avatar
                                ☺
                                Scritto da
                                altg
                                utente che non utiene
                                il 2014-11-01 23:00:14.0 alle 2014-11-01 23:00:14.0
                                Trollate totali: 11540
                                Re: Ci si capisce, vero?
                                > > > > > Buona serata.
                                > > > >
                                > > > > Meno male che c'è sassofono: magari fra le sue critiche salta anche fuori qualcosa di utile.
                                > > >
                                > > > Sshhh... e` per quello che posto la roba ogni tanto.
                                > > > Ma se glielo dici e` abbastanza dispettoso da non cacarmela piu`. Fantasma
                                > >
                                > > ormai lo sa
                                >
                                > Azz, dovevo star zitto. Triste
                                > Comunque mi ammutolisce vedere quante cose sa sassofono.

                                E` un tipo curioso e molto meticoloso. Mi ha un po' colpito il fatto che trovasse NECESSARIO capire perche`, qualora la famosa istruzione sbagliata fosse stata veramente una combinazione non valida di opcode e operandi, il sistema non avesse intercettato l'eccezione.

                                Comunque, e` un ganzo. Ficoso
                    • Avatar
                      ☺
                      Scritto da
                      avvelentani
                      Cubicolario
                      il 2014-11-02 09:23:59.0 alle 2014-11-02 09:23:59.0
                      Trollate totali: 18184
                      Re: Ci si capisce, vero?
                      Scritto da: altg
                      > > Il codice di strlen e` questo: http://www.eglibc.org/cgi-bin/viewvc.cgi/trunk/lib...
                      >
                      > p.s. comunque la tattica per trovare il terminatore confrontando 4 byte per volta e` carina, non la sapevo e ora la importo in text::FromByteString. Intanto, pero`, volevo farti notare che L.in.oleum, allineando tutto a word del processore, nel fare la stessa cosa per poter sfruttare confronti su 4 byte per volta, puo` saltare questo:
                      >
                      >
                      > /* Handle the first few characters by reading one character at a time.
                      > Do this until CHAR_PTR is aligned on a longword boundary.  */
                      > for (char_ptr = str; ((unsigned long int) char_ptr
                      > 			& (sizeof (longword) - 1)) != 0;
                      > ++char_ptr)
                      > if (*char_ptr == '\0')
                      > return char_ptr - str;
                      > 

                      >
                      > Sei ancora convinto che tutti questi vantaggi non ci siano?

                      Si`, perche' se devo gestire una stringa che non e` 4-allineata non solo mi devo scrivere l'equivalente di quel codice ma lo devo fare usanto shift e bitmask.
                      I think happiness is love
                      - Vladimir Putin
          • Avatar
            ☺
            Scritto da
            altg
            utente che non utiene
            il 2014-10-31 17:24:21.0 alle 2014-10-31 17:24:21.0
            Trollate totali: 11540
            Re: Ci si capisce, vero?
            > (tra l'altro chi e` che setta EDI/w?)

            Ah, m'ero scordato questa: lo carica il modulo di run-time. EDI sugli Intel e` l'origine dell'area dati dell'applicazione, relativamente alla quale avviene la mappatura degli indirizzi (non solo di dati statici, ma anche di blocchi di heap). In un sorgente, EDI si chiama w (per "workbench"). In ambito multithreaded, EDI e` specifico di un thread: ogni thread ha il suo workbench, e quel che nel sorgente si potrebbe chiamare una variabile o un buffer statico globale, e` in pratica thread-local.
    • Avatar
      ☺
      Scritto da
      ::1
      il 2014-11-02 15:42:43.0 alle 2014-11-02 15:42:43.0
      Trollate totali: 12321
      Re: Ci si capisce, vero?
      Scritto da: altg

      I sorgenti del parser sono scritti in linoleum? Se sono scritti in un linguaggio umanamente comprensibile ce li puoi mostrare?
      Young professional woman and busy mom.
      • Avatar
        ☺
        Scritto da
        altg
        utente che non utiene
        il 2014-11-02 16:47:40.0 alle 2014-11-02 16:47:40.0
        Trollate totali: 11540
        Re: Ci si capisce, vero?
        > I sorgenti del parser sono scritti in linoleum? Se sono scritti in un linguaggio umanamente comprensibile ce li puoi mostrare?

        I sorgenti del parser del compilatore di L.in.oleum 4 sono scritti in javascript. Girano nel browser, appoggiandosi per la lettura delle librerie a un miniserver nodeJS (una versione downscaled di JS Mary Lou). Il linker e` un modulo del webserver che risponde a un POST del disassemblato (l'output testuale del compilatore) all'indirizzo "http://localhost:4048/link".

        Il compilatore e` un monoblocco javascript di 13500 righe, poi c'e` l'assembler specifico per x86 che ne conta altre 3150 (ovviamente e` switchabile con altri "semi-assemblers"). Li chiamo semi-assemblers perche` sono assemblers incompleti: si limitano ad assemblare il subset di istruzioni e modalita` d'indirizzamento contemplate dalla sintassi L.in.oleum.

        In cima a tutto c'e` il front-end, cioe` il javascript che anima l'interfaccia, e che include un piccolo text editor per editare i sorgenti. Per navigare tra le librerie, le righe "include" vengono evidenziate come links che porta alla corrispondente libreria.

        Di parser non ce n'e` uno solo: ce n'e` uno principale che isola le linee dei sorgenti, le istruzioni e le espressioni, ma poi c'e` il parser delle espressioni, quello degli operandi, quello dei ranges (inline arrays) e delle stringhe.

        Ma a che ti servono i sorgenti del/dei parser? Per curiosita`? Newbie, inesperto

        Fra l'altro sono ancora un po' in evoluzione, spuntano spesso degli errorini mentre scrivo le prime librerie: il compilatore e` in rodaggio, insomma...
        • Avatar
          ☺
          Scritto da
          ::1
          il 2014-11-02 16:55:17.0 alle 2014-11-02 16:55:17.0
          Trollate totali: 12321
          Re: Ci si capisce, vero?
          Scritto da: altg
          > Ma a che ti servono i sorgenti del/dei parser? Per curiosita`? Newbie, inesperto

          Sto imparando a parsare come fanno i grandi, volevo vedere come facevi tu.
          Niente generatore di parser quindi, né grammatiche del linguaggio.
          Young professional woman and busy mom.
          • Avatar
            ☺
            Scritto da
            altg
            utente che non utiene
            il 2014-11-02 17:01:58.0 alle 2014-11-02 17:01:58.0
            Trollate totali: 11540
            Re: Ci si capisce, vero?
            > > Ma a che ti servono i sorgenti del/dei parser? Per curiosita`? Newbie, inesperto
            >
            > Sto imparando a parsare come fanno i grandi, volevo vedere come facevi tu.

            Um... io sono un tipo atipico, come ben puo` confermarti il Prof. Avvelentani. Uno che pensa parecchio lateralmente, quasi di sbieco, solo un po' piu` giu` a babordo. Anonimo

            > Niente generatore di parser quindi, né grammatiche del linguaggio.

            No, mai provato generatori di parsers. Non saprei quanto sarebbe comodo un generatore di parsers, puo` darsi che sarebbe comodo, oppure che per fargli fare quello che vuoi tu debba pregarlo in cinese tradizionale. Boh. Comunque io mi trovo bene a scriverli per conto mio. Quello di Lino4 guarda carattere per carattere in ordine piu` o meno LTR, ma ogni tanto fa una puntatina ahead per distinguere qualche caso, tipo quelli di "-" e "-->", nel senso che si chiede "che viene dopo il trattino?".

            ps. ah ecco, ho ricontrollato, e` essenzialmente un LALR(2), Look-Ahead Left-to-Right con 2 tokens "presi piu` avanti". Ma non lo scrivo seguendo qualche modello ideale, lo scrivo partendo da un'idea di comodita`, e poi ce lo modello intorno. Per esempio e` +2 perche` appunto trovo convenienti i simboli "-->" e "<--" per push e pop in/da stack, perche` sono molto visibili e questo dovrebbe aiutare a evitare errori, visto che sbagliare a manipolare lo stack a basso livello e` catastrofico. A bocca aperta

            **Modificato dall'autore il 02.11.2014 17:13**
            • Avatar
              ☺
              Scritto da
              ::1
              il 2014-11-02 17:12:02.0 alle 2014-11-02 17:12:02.0
              Trollate totali: 12321
              Re: Ci si capisce, vero?
              Scritto da: altg
              > > > Ma a che ti servono i sorgenti del/dei parser? Per curiosita`? Newbie, inesperto
              > >
              > > Sto imparando a parsare come fanno i grandi, volevo vedere come facevi tu.
              >
              > Um... io sono un tipo atipico, come ben puo` confermarti il Prof. Avvelentani. Uno che pensa parecchio lateralmente, quasi di sbieco, solo un po' piu` giu` a babordo. Anonimo

              Non è un approccio per forza di cose sbagliato, ci sono molti che preferiscono il tuo approccio per questione di flessibilità.

              > > Niente generatore di parser quindi, né grammatiche del linguaggio.
              >
              > No, mai provato generatori di parsers. Non saprei quanto sarebbe comodo un generatore di parsers, puo` darsi che sarebbe comodo, oppure che per fargli fare quello che vuoi tu debba pregarlo in cinese tradizionale. Boh. Comunque io mi trovo bene a scriverli per conto mio. Quello di Lino4 guarda carattere per carattere in ordine piu` o meno LTR, ma ogni tanto fa una puntatina ahead per distinguere qualche caso, tipo quelli di "-" e "-->", nel senso che si chiede "che viene dopo il trattino?".

              Sì, ti tocca litigare un po' per fargli fare quello che vuoi. Un vantaggio è la portabilità, metti che un domani vuoi cambiare l'implementazione in un altro linguaggio/piattaforma, sarà molto più facile visto che la grammatica è quella. L'altro vantaggio è che l'approccio formale evita alcuni tipi di bug nell'implementazione (qualcuno ha detto parser di php?).
              Young professional woman and busy mom.
              • Avatar
                ☺
                Scritto da
                altg
                utente che non utiene
                il 2014-11-02 17:20:32.0 alle 2014-11-02 17:20:32.0
                Trollate totali: 11540
                Re: Ci si capisce, vero?
                > > > > Ma a che ti servono i sorgenti del/dei parser? Per curiosita`? Newbie, inesperto
                > > >
                > > > Sto imparando a parsare come fanno i grandi, volevo vedere come facevi tu.
                > >
                > > Um... io sono un tipo atipico, come ben puo` confermarti il Prof. Avvelentani. Uno che pensa parecchio lateralmente, quasi di sbieco, solo un po' piu` giu` a babordo. Anonimo
                >
                > Non è un approccio per forza di cose sbagliato, ci sono molti che preferiscono il tuo approccio per questione di flessibilità.
                >
                > > > Niente generatore di parser quindi, né grammatiche del linguaggio.
                > >
                > > No, mai provato generatori di parsers. Non saprei quanto sarebbe comodo un generatore di parsers, puo` darsi che sarebbe comodo, oppure che per fargli fare quello che vuoi tu debba pregarlo in cinese tradizionale. Boh. Comunque io mi trovo bene a scriverli per conto mio. Quello di Lino4 guarda carattere per carattere in ordine piu` o meno LTR, ma ogni tanto fa una puntatina ahead per distinguere qualche caso, tipo quelli di "-" e "-->", nel senso che si chiede "che viene dopo il trattino?".
                >
                > Sì, ti tocca litigare un po' per fargli fare quello che vuoi. Un vantaggio è la portabilità, metti che un domani vuoi cambiare l'implementazione in un altro linguaggio/piattaforma, sarà molto più facile visto che la grammatica è quella. L'altro vantaggio è che l'approccio formale evita alcuni tipi di bug nell'implementazione (qualcuno ha detto parser di php?).

                Boh, c'erano dei bug nel parser di php?
                Vabbe' tanto non me ne sono accorto. Anonimo

                Qui i bug piu` che nel parser li trovo nel semi-assembler: e` difficile testarne tutte le combinazioni di opcode e operandi, e ogni tanto ne salta fuori una che fa ka-boom. Triste
<softv>

Pagina generata in 355 millisecondi

Utenti attivi: 8 nell'ultimo minuto, 20 negli ultimi cinque minuti, 44 negli ultimi 15 minuti