Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - CrashTest

Pages: [1]
1
2D / Ridimensionamento immagine
« on: April 05, 2017, 09:49:09 PM »
Sera ragazzi,

scusate il lungo periodo di assenza ma in questo periodo sono molto impegnato con l'uni.
Sono qui perchè ho un piccolo problema. Qualcuno ha mai avuto a che fare con l'elaborazione di immagini? Devo scalare uno sprite per un videogioco (ma una immagine qualunque fa lo stesso) per fare in modo che si ridimensioni in base alla grandezza della finestra. Non posso usare nessuna libreria ad hoc, nessun motore grafico, niente di niente. Solo C++ ed una libreria multimediale (SFML). Per fare questo sto immaginando l'immagine come una serie di punti in uno spazio euclideo a due dimensioni. Essendo una immagine raster, in caso di trasformazioni geometriche questa è soggetta a perdita di qualità.

Per scalare l'immagine e ricostruire i colori avevo pensato di usare l'interpolazione che mi permette approssimare il valore di una funzione nell' intorno di un punto. Essendo l'immagine in un piano a due dimensioni ho pensato ad una interpolazione bilineare (semplicemente una interpolazione lineare ma in funzione di due variabili, in questo caso x ed y, gli assi del piano) che dato un punto -in questo caso sarebbe il pixel- analizza i pixel più vicini per trovare il miglior valore RGB per quel punto. Parlando con un ragazzo però, è uscita fuori l'interpolazione nearest-neighbor che a differenza della bilineare dovrebbe essere più semplice da implementare. Ora sono ancora più confuso di prima, quale sistema secondo voi è più preciso? Avete qualche suggerimento?

2
Tools / Valgrind - Breve introduzione
« on: March 15, 2017, 07:23:33 PM »
Ciao a tutti, in questo post daremo uno sguardo veloce a Valgrind per capire cosa è e a cosa serve. Nei prossimi articoli analizzeremo nel dettaglio i diversi tools e vedremo come utilizzarli al meglio.

Valgrind è uno strumento multiuso, un coltellino svizzero dei programmatori. Questo ci aiuta nei casi più disparati: dal profiling al debugging della memoria per Linux.Inizialmente era disponibile per x86, dalla versione 3 lo è anche per AMD64 ed altre architetture. Valgrind ci permette di eseguire il nostro programma nel suo ambiente che controlla l'utilizzo della memoria, come ad esempio le chiamate a malloc o free (o new e delete nel caso di C++). Se si scrive fuori la fine di un array, ci si dimentica di liberare un puntatore o altri errori o sviste di questo tipo, Valgrind è in grado di rilevarlo. Dal momento che questi sono problemi abbastanza comuni, vedremo come utilizzare Valgrind per trovare questi tipi di problemi di memoria, anche se Valgrind è uno strumento molto più potente e che può fare molto di più.

Il comando per lanciare Valgrind è:

Code: You are not allowed to view links. Register or Login
$ valgrind --tool=nome_tool program_pathnome_tool è il nome dello strumento da usare e program_path è il percorso del programma da lanciare con Valgrind.
I tools più conosciuti ed utilizzati sono:

  • Memcheck
  • Addrcheck
  • Massif
  • Cachegrind
  • Callgrind
  • Helgrind

Memcheck è un rilevatore di errori in memoria. Aiuta ai programmatori a scrivere programmi (specialmente in  C e C ++) consistenti e senza problemi in memoria.

Addrcheck è una versione semplificata ed alleggerita di Memcheck. È identico a MemCheck in tutto e per tutto, ad eccezione di un dettaglio importante: non fa controlli sugli Undefined values. Questo significa che Addrcheck è più veloce di Memcheck ed utilizza meno risorse (in termini di memoria e processore).

Massif  è un profiler dell'heap. Ci permette di analizzare lo stato dello heap e ci permette quindi di scrivere programmi che utilizzano meno memoria.

Cachegrind è un profile che si occupa principalmente della cache e della predizione delle diramazioni. Ci aiuta a creare programmi più veloci e performanti.

Callgrind invece è uno strumento di profiling mantiene uno storico delle chiamate tra le funzioni in esecuzione in un programma, una sorta di grafo delle chiamate.

Helgrind è un rivelatore di errori nei thread. Ci aiuta a fare i programmi multi-threaded più corretto.

Nel prossimo post vedremo come usare Memcheck e Addrcheck, nel frattempo vi saluto e vi invito segnalare eventuali errori.
Saluti, CrashTest

Fonte: You are not allowed to view links. Register or Login

3
Sandbox / prova tag code
« on: February 11, 2017, 05:59:35 PM »
Code: (php) You are not allowed to view links. Register or Login
<?php
$a
=6;
echo 
$a;
?>


Code: (c) You are not allowed to view links. Register or Login
#include<stdio.h>

int main(void)
{
    printf("hello world");
}

Col php funziona il syntax highlighting usando "code=php", con gli altri no ahah

4
C / Ottimizzazione - piccoli accorgimenti
« on: February 11, 2017, 05:38:08 PM »
Salve a tutti, ultimamente, lavorando ad un programma in C, mi è capitato di avere a che fare con qualche piccolo accorgimento riguardante l'ottimizzazione. Ho trovato poche informazioni in italiano quindi ho studiato dalle documentazioni di GCC e da vari articoli che parlano degli "internals" del linguaggio, decidendo di condividere questi, anche se piccoli, accorgimenti con voi: potrebbero tornarvi utili :D
Cercherò di essere il più chiaro possibile ed evitare fraintendimenti. Per comprendere questo articolo sono richieste delle conoscenze base relative ad array e puntatori.
Bene, dopo questa noiosa introduzione passiamo al dunque.

Nell'ottimizzazione di un programma, una delle prime cose da considerare è l'uso di array e indici. Per accedere ad un elemento di un array usando gli indici il compilatore dovrà eseguire una serie di calcoli, soprattutto moltiplicazioni. Il mio consiglio se si vuole ottimizzare un programma che fa largo uso di array è quello di vedere queste strutture per quello che realmente sono: un puntatore al primo elemento al quale applicare l'aritmetica dei puntatori. A primo impatto questo tipo di approccio potrebbe sembrare ostico, ma è abbastanza semplice, basta solo ragionarci un po' e una volta entrati nell'ottica diventa come contare normalmente. Usando l'aritmetica dei puntatori, l'incremento di un puntatore si riduce ad una banale somma che richiede molte meno risorse computazionali.
Snippets come quelli dell'esempio sottostante sarebbe meglio evitarli se il nostro obbiettivo è fare un programma molto più veloce ed ottimizzato.
Code: You are not allowed to view links. Register or Login
void somma_elementi(int *primo, int *secondo, int *somma, int elementi)
{
  for(int i = 0; i < elementi; i++)
    somma[i] = primo[i] + secondo[i] ;
}

Un'alternativa del tutto equivalente a questo codice (anche se migliorabile) potrebbe essere questa:
Code: You are not allowed to view links. Register or Login
void somma_elementi(int *primo, int *secondo, int *somma, int elementi)
{
  for(int i = 0; i < elementi; i++)
    *(somma + i) = *(primo + i) + *(secondo + i);
}

Possiamo notare come questo codice potrebbe essere riscritto in maniera leggermente differente e più chiara utilizzando l'operatore di post-incremento ottenendo uno snippet di questo tipo:
Code: You are not allowed to view links. Register or Login
void somma_elementi(int *primo, int *secondo, int *somma, int elementi)
{
  for(int i = 0; i < elementi; i++)
      *(somma++) = *(primo++) + *(secondo++);
}

Riflettendoci un attimo possiamo notare che le operazioni di post-incremento sono leggermente più lente di quelle di pre-incremento: questo perchè il compilatore è obbligato a conservare una copia del vecchio valore, restituirlo non ancora incrementato, eseguire il codice ed effettuare l'incremento. Se si tratta di poche iterazioni tutto questo non ha un peso rilevante, ma vi posso assicurare che su un numero eleveto di iterazioni la differenza in termini di prestazioni e complessità computazionale si nota. Per questo sono arrivato ad una soluzione che usi solo l'aritmetica dei puntatori e il pre-incremento.
Questo dovrebbe essere il risultato finale:
Code: You are not allowed to view links. Register or Login
void somma_elementi(int *primo, int *secondo, int *somma, int elementi )
{
    --primo;
    --secondo;
    --somma
    for(int i = 0; i < n; i++)
        *(++somma) = *(++primo) + *(++secondo);
}

Nello snippet qui sopra ho decrementato i puntatori per poi incrementarli nel ciclo for senza perdere informazioni. Arrivato a questo punto ero contento del mio programma perchè ero riuscito a ottimizzarlo e a compattare il codice. Però non è finita qui: c'è un grave errore nel mio programma, riuscite a notarlo da soli? Ok, ve lo dico nel caso non lo aveste notato. Parlando con un amico e rileggendo un attimo il manuale dell'ANSI C, nel paragrafo 6 (circa array e puntatori) ho notato che quello che avevo fatto non andava per niente bene: nonostante questo programma funzioni sulla quasi totalità delle CPU è presente un "undefined behavior", un comportamento indefinito. Decrementare il puntatore al primo elemento di un array non fa altro che farmi uscire dalla memoria dedicata all'array. Su alcuni compilatori o CPU questo non fa altro che bloccare il programma e lanciare una eccezione che potrebbe essere quella di Out of Memory o quella di Segmentation Fault. Per questo mi sono subito precipitato a correggere questo obbrobrio: avere codice non sicuro mi fa stare male. In questo caso la correzione era piuttosto banale e scontata, ve la mostro:
Code: You are not allowed to view links. Register or Login
void somma_elementi_ottimizzata(int *primo, int *secondo, int *somma, int elementi)
{
    for(int i = 0; i < elementi; i++)
    {
        *somma = *primo + *secondo;
        ++primo;
        ++secondo;
        ++somma;
    }
}

Perfetto, adesso ho l'anima in pace e il programma funziona correttamente senza un codice “unsafe”. Arrivati a questo punto possiamo provare ad analizzare brevemente questo pezzo di codice e relazionarlo ai precedenti. Come possiamo vedere, rispetto ai primi snippets non uso ne indici ne operatori di post-incremento, uso semplicemente l'aritmetica dei puntatori e gli operatori di pre-incremento.
Facendo invece un confronto con lo snippet precedente notiamo chiaramente come evitando il decremento all'inizio possiamo ridurre i cicli di clock necessari risparmiando tempo e soprattutto senza riscontrare problemi di "undefined behavior".

Spero di essere stato abbastanza chiaro, per qualsiasi dubbio o segnalazione di errori scrivete pure nei commenti. A breve pubblicherò altre guide, una riguardante l'aritmetica dei puntatori.

Saluti,
CrashTest
Fonte: You are not allowed to view links. Register or Login

5
Tips from the Community - Consigli dalla Comunità / Zoom font
« on: February 07, 2017, 11:45:10 AM »
Salve a tutti,
vorrei proporre, anche se non con molta fretta la possibilità di ingrandire o ridurre la dimensione del font. Una sorta di questo:

Questo se non richiede molto lavoro

6
Tips from the Community - Consigli dalla Comunità / [RISOLTO] LaTeX
« on: November 25, 2016, 02:23:58 PM »
Per questioni di comodità chiedo se è possibile implementare sul portale LaTeX ed utilizzare un editor di testo più avanzato perchè diventa spossante scrivere testi abbastanza lunghi ed eterogenei (immagini, testo e codice). Voi che ne pensate?

7
GNU-Linux / Gestione dei processi in Linux - Pt. 1
« on: November 18, 2016, 07:54:43 PM »
Gestione dei processi in Linux

1. Cosa è un processo

Un processo è un programma in esecuzione, viene elaborato da un processore sotto la supervisione del Sistema Operativo. La loro gestione è affidata allo scheduler che tramite algoritmi di scheduling ne pianifica l'esecuzione stabilendo un ordine temporale e privilegiando alcune richieste (che rispettano determinati criteri) stabilendo code di priorità. Questa pratica si chiama politica di scheduling. Non scriverò ulteriormente su questo, magari farò un altro thread parlando dei processi in generale :)


1.2. Creazione di un processo

Ora che abbiamo rivisto cosa è un processo vediamo come questo viene creato.
Gli eventi più comuni,a seconda di quello che sceglie il programmatore o scelte fatte dal sistema operativo, che possono dar luogo ad un processo sono:
  • Inizializzazione del sistema
  • Avvio di nuovi batch
  • Avvio di un nuovo processo da parte dell'utente
Condivisione delle risorse:
  • Padre e figlio condividono tutte le risorse
  • Padre e figlio condividono alcune risorse
  • Padre e figlio non condividono alcuna risorsa
Esecuzione/sincronizzazione:
  • Il padre e figlio procedono in modo concorrente
  • Il padre attende il completamento dell’esecuzione del figlio
1.3. Processi in Linux

Ora che conosciamo le varie modalità di creazione di un processo vediamo come questi funzionano su sistemi Unix/Linux.
Iniziamo col dire che un processo su Linux è caratterizzato dalla sua immagine.

L'immagine di un processo consiste di:

  • Immagine di memoria (virtual address space)
  • valore dei registri (CPU status)
  • tabella dei file (file descriptor table)
  • directory di lavoro
Quando un processo viene creato a questo e? assegnato uno spazio virtuale degli indirizzi (virtual address space). Questo spazio è usato dal processo durante tutta la sua esecuzione.
Le informazioni di sistema relative ad un processo sono invece mantenute in due aree: l' user space e la process table.
L' user space di un processo e? localizzato al termine della parte superiore dell’address space del processo ma, tranne in alcune eccezioni (monitor mode) questo non è accessibile. Contiene:

  • Puntatore al processo nella process table
  • Tabella dei file
  • Directory di lavoro corrente
Ci tengo inoltre a sottolineare che questa area può essere sottoposta a swap.

La process table contiene le principali informazioni mantenute dal sistema operativo rispetto ad ogni processo. È situata nella memoria del kernel del sistema operativo e non puo? essere sottoposta a swap. Ogni ingresso (entry) della tabella contiene:

  • PID del processo
  • PID del processo padre (PPID)
  • ID utente (user ID)
  • Stato
  • Descrittore di evento (ad esempio, un processo in stato di sleeping, indica l’evento per cui il processo e? in attesa)
  • Posizione nella user area
  • Priorita?
Nei sistemi Unix/Linux per vedere le informazioni contenute nella process table e nell' user space è possibile usare il comando: ps.

1.4. Struttura della memoria

Lo spazio di indirizzi virtuale di un processo e? diviso in segmenti, cioe? un insieme di indirizzi virtuali ai quali il processo puo? accedere. Se tenta di accedere in zone di memoria che non gli competono questo processo vai in SegFaul (Segmentation Fault). Solitamente un programma (parlerò di quelli scritti in linguaggio C) viene suddiviso nei seguenti segmenti:
  • Il segmento di testo (text segment). Contiene il codice del programma le funzioni di libreria da esso utilizzate e le costanti. Questo spazio è condiviso fra tutti i processi che eseguono lo stesso programma ed è impostato in sola lettura per evitare sovrascritture che modifichino le istruzioni. Viene allocato dalla funzione exec() all’avvio del programma e resta invariato per tutto il tempo di esecuzione del processo;
  • Il segmento dei dati (data segment). Contiene le variabili globali (cioè quelle definite al di fuori di tutte le funzioni che compongono il programma) e le variabili statiche. Questo segment è diviso a sua volta in due parti: variabili inizializzate e variabili non inizializzate. Non scriverò altro su questo per non allungare troppo il brodo, magari farò un nuovo thread;
  • Lo heap. Qui che avviene l’allocazione dinamica della memoria; puo? essere ridimensionato allocando e deallocando la memoria dinamica con le apposite funzioni malloc(), calloc(), free(), etc. (funzioni che si appoggiano su chiamate di sistema. In realtà è il sistema operativo che alloca la memoria).
  • Lo stack, che contiene, appunto lo stack del programma. Tutte le volte che si effettua una chiamata ad una funzione e? qui che viene salvato l’indirizzo di ritorno ed altre informazioni ausiliare. La funzione chiamata alloca qui lo spazio per le sue variabili locali: grazie a questo spazio le funzioni possono essere chiamate ricorsivamente. Al ritorno dalla funzione, lo spazio e? automaticamente rilasciato e ripulito. La pulizia in C e C++ viene fatta dal chiamante in quanto non sono dotati di garbage collector. La dimensione di questo segmento aumenta seguendo la crescita dello stack del programma, ma non viene ridotta quando quest’ultimo si restringe. Questo potrebbe causare problemi di frammentazione.
Su questo ci sarebbe molto molto altro da dire in quanto al di là di spazi di memoria sono anche strutture dati, magari potremmo discuterne

P.S.: Mi scuso per eventuali errori e differenze tra i caratteri ma con questo editor è molto difficile scrivere un testo formattato. Sto riportando il tutto in un documento LaTex, magari se vi interessa, al termine pubblicherò un pdf.
P.P.S.:Nella prossima parte vedremo le syscall utilizzate per gestire i processi. Attendo commenti per capire se un argomento del genere possa interessare al forum

8
Introduce yourself - Presentazioni / Mi presento :D
« on: November 16, 2016, 05:19:34 PM »
Ciao a tutti,

mi chiamo Cosimo, 19 anni, sono di Taranto e sono un appassionato di informatica.
Sono un utente linux da ormai 3 anni. La mia esperienza è iniziata nel 2013 quando decisi di provare Debian, dopo 3-4 mesi provai ad reinstallare lo stesso sistema, questa volta però nella versione minimale. Dopo 7-8 mesi, per provare qualcosa di nuovo e di diverso decisi di installare Arch, beh nulla da dire, da allora mai più cambiato, mi trovo molto bene; un sistema rolling release, sempre aggiornato, ottima community e cosa molto molto comoda: l'AUR, un repository community-driven, ben fornito e tenuto sempre aggiornato. Mi interesso di programmazione, principalmente C/C++, nel tempo libero per curiosità ho provato anche PHP, con il quale per divertirmi ho provato a sviluppare un piccolo framework (che rilascerò appena lo riterrò presentabile e adatto per sfruttare al meglio PHP 7) per la gestione dinamica dei contenuti, sviluppato in PHP 5.6  sfruttando l'OOP e seguendo il pattern MVC. Per interfacciarmi con i Database ho usato PDO.

Bene, penso di aver scritto già troppo per una presentazione, ci becchiamo nel forum ed un in bocca al lupo ai creatori :D

Pages: [1]