Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Saturday, 16 April 2011

wc recursively in perl

Πάντα χρειαζόμουν ένα απλό script που να μετράει τις γραμμές κώδικα σε αρχεία και σε φακέλους αλλά και σε όλα τα αρχεία που βρίσκονται στους υποφακέλους. Και μιας και αυτό το διάστημα μαθαίνω perl είπα να δοκιμάσω την τύχη μου. Βέβαια το παρακάτω δεν κάνει τίποτε από ένα system call σε μια εντολή με pipes (που χρησιμοποιεί και awk) και να τυπώνει το αποτέλεσμα:

#!/usr/bin/env perl
if ( @ARGV > 0 )
{
$count = `find $ARGV[0] -type f -exec wc -l {} \\; | awk '{total += \$1} END{print total}'`;
print $count;
}
else
{
print "No arguments!\n";
}

Thursday, 24 June 2010

Σκέψεις για το μέλλον του ελεύθερου λογισμικού

Το ελεύθερο λογισμικό τα έχει όλα: κώδικα, προγραμματιστές, αποθετήρια κώδικα. Αυτό όμως που πραγματικά λείπει από το ελεύθερο λογισμικό είναι η συνδυασμένη προσπάθεια. Βλέπουμε να υπάρχουν δεκάδες προγράμματα που κάνουν λίγο ή πολύ την ίδια δουλειά. Αντί ένας προγραμματιστής να αρχίσει να δουλεύει σε ένα υπάρχον πρόγραμμα και να διορθώσει τα τυχόν σφάλματα ή να προσθέσει καινούριες δυνατότητες ξεκινάει ένα δικό του με την ελπίδα να είναι καλύτερο από το προηγούμενο. Αυτό δεν είναι απαραίτητα αρνητικό, μιας και δημιουργούνται νέα προγράμματα, υπάρχει ανταγωνισμός και ο ανταγωνισμός οδηγεί στην πρόοδο. Αλλά πιστεύω ότι αν υπήρξε συνδυασμένη προσπάθεια και οργανωμένος σχεδιασμός θα αποφεύγαμε την πολλαπλή ανακάλυψη του τροχού.

Thursday, 22 October 2009

Ghostscript


Η αποθήκευση ορισμένων σελίδων από αρχεία pdf, ps, eps ώς ξεχωριστά αρχεία καθώς και η συγχώνευση πολλών αρχείων pdf, ps, eps είναι αρκετά εύκολη με το πρόγραμμα ghostscript. Από τη γραμμή εντολών το πρόγραμμα αυτό εκτελείται πληκτρολογόντας gs. 


H αποθήκευση ορισμένων σελίδων ως νέο αρχείο γίνεται με την παρακάτω εντολή:

gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=output.pdf -dFirstPage=first -dLastPage=last input.pdf

όπου output.pdf είναι το όνομα του καινούριου αρχείου, first είναι ο αριθμός της πρώτης σελίδας που θέλουμε να εξάγουμε, last είναι ο αριθμός της τελευταίας σελίδας που θέλουμε να εξάγουμε, και input.pdf είναι το όνομα του αρχικού αρχείου.


Η συγχώνευση πολλών αρχείων pdf γίνεται με την παρακάτω εντολή:

gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=output.pdf input1.pdf input2.pdf input3.pdf

όπου output.pdf είναι πάλι το όνομα του νέου αρχείου και input1.pdf, input2.pdf input3.pdf είναι τα ονόματα των αρχείων προς συγχώνευση.


Και ένα script που αυτοματοποιεί κάπως την πληκτρολόγηση δίνεται παρακάτω:


#!/bin/csh -f

# pdfextract - extracts pages from a pdf

# 2009.06.19 - written by DP

set output=0

set com=`basename $0`

set USAGE="usage: $com [-f FirstPage] [-l LastPage] [-o OutputFile] [file]"

set argv=(`getopt f:l:o: $*`)

set errflg=$status

set first=1

set last=0

set pdffile=""

if ($errflg == 0) then

while ("$argv[1]" != "--")

switch ($argv[1])

case -f:

set first=$argv[2]

shift argv

breaksw

case -l:

set last=$argv[2]

shift argv

breaksw

case -o:

set output=1

set OutputFile=$argv[2]

shift argv

breaksw

default:

set errflg=1

breaksw

endsw

shift argv

end

shift argv

endif

if ( $#argv == 0 ) then

set errflg=2

endif

if ($errflg != 0) then

echo "$USAGE"

exit 1

endif

if ($output == 0) then

if ( $last == 0 ) then

set OutputFile="`basename -s .pdf $1`$first-end.pdf"

else

set OutputFile="`basename -s .pdf $1`$first-$last.pdf"

endif

endif

foreach i ( ${argv} )

set pdffile="$pdffile $i"

end

if (-e $OutputFile) then

echo "$OutputFile already exists"

exit 1

endif

if ( $last == 0 ) then

set gsargs=""

else

set gsargs="-dLastPage=$last"

endif

gs -q -sPAPERSIZE=a4 -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$OutputFile -dFirstPage=$first $gsargs $pdffile


ΥΓ. Προσοχή που αλλάζει η γραμμή και που συνεχίζεται.

Tuesday, 24 February 2009

Γραφικά με GTK+

Γενικά
Θέμα του οδηγού αυτού είναι τα γραφικά με τη χρήση της βιβλιοθήκης GTK+. Ο επίσημος οδηγός στα αγγλικά βρίσκεται εδώ: http://library.gnome.org/devel/gtk-tutorial/stable/ Τα παραδείγματα που χρησιμοποιώ βρίσκονται και στον αρχικό οδηγό. Παρ'όλ' αυτά δεν πρόκειται για μετάφραση μιας και ο μεταφραστής είναι προδότης (traduttore traditore :D ) αλλά για έναν καινουριο οδηγό.
Η GTK+ είναι μια βιβλιοθήκη που ξεκίνησε από το πρόγραμμα GIMP και εξελίχθηκε σε αυτόνομη βιβλιοθήκη. Παρέχει τις βασικές λειτουργίες για γραφικά, GUI, συμβάντα, κ.α.

Προαπαιτούμενα
Για τη χρήση της βιβλιοθήκης θα χρειαστεί να εγκαταστήσουμε μερικά πακέτα, τα build-essential, gtk+-2.0, pkg-config. To build-essential μας δίνει το GNU C μεταγλωττιστή, τo εργαλείo make κ.α., το gtk+-2.0 είναι η βιβλιοθήκη, και το pkg-config είναι ένα βοηθητικό πρόγραμμα που διαχειρίζεται τις παραμέτρους για το gcc. Aνοίγουμε το τερματικό και πληκτρολογούμε:

sudo apt-get install build-essential gtk+-2.0 pkg-config

Το πρώτο πρόγραμμα
Στον παρών οδηγό θα ασχοληθούμε με c, αλλά υπάρχουν και διεπιφάνειες και για άλλες γλώσσες προγραμματισμού. Ανοίγουμε ένα αρχείο bla.c και γράφουμε μέσα τον παρακάτω κώδικα:

#include <gtk/gtk.h>

int main( int argc,
char *argv[] )
{
GtkWidget *window;

gtk_init (&argc, &argv);

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);

gtk_main ();

return 0;
}

Το αποθηκεύουμε και έπειτα το μεταγλωττίζουμε με την εντολή:

gcc bla.c -o bla `pkg-config --cflags --libs gtk+-2.0`

Προσοχή παραπάνω είναι ` και όχι ', αυτό σημαίνει αντικατάσταση του αποτελέσματος της εντολής pkg-config --cflags --libs gtk+-2.0, την οποία αν εκτελέσουμε μόνη της θα δούμε μια λίστα από διαδρομές, αρχεία, βιβλιοθήκες τα οποία είναι παράμετροι για το gcc. Φυσικά αν ξέρουμε τι κάνουμε αυτές τις παραμέτρους μπορούμε να τις τροποποιήσουμε με το χέρι.
Τρέχοντας το πρόγραμμα:

./bla

θα δούμε ένα παράθυρο που δεν έχει τη δυνατότητα τερματισμού εκτός από το ctrl+c.

H πρώτη γραμμή λέει στο πρόγραμμά μας ποια αρχεία να συμπεριλάβει. Η διαδρομή των αρχείων καθορίζεται από την εντολή pkg-config --cflags --libs gtk+-2.0. Μετά από τον απαραίτητο ορισμό του κυρίως προγράμματος main χρειαζόμαστε την κλήση της συνάρτησης gtk_init. Σε όλα τα προγράμματα αυτή η κλήση είναι απαραίτητη εκτός κι αν ξέρουμε τι κάνουμε. Όλες τις παραμέτρους από τη γραμμή εντολών που έχουν να κάνουν με τη gtk τις αφαιρεί από τη λίστα των παραμέτρων και τις υπόλοιπες μπορεί ο χρήστης να τις χρησιμοποιήσει όπως θέλει.

Στην gtk σχεδόν όλα είναι GtkWidgets. Έτσι και το παράθυρό μας είναι ένας δείκτης τύπου GtkWidget (GtkWidget *window). Αυτός είναι ο ορισμός του αλλά το παράθυρο δημιουργείται για πρώτη φορά στη γραμμή:

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

Δημιουργείται όμως στη μνήμη, τίποτε δε φαίνεται ακόμη στην οθόνη. Η εντολή που το προβάλλει είναι η:

gtk_widget_show (window);

Αλλά πάλι δε συμβαίνει τίποτε. Αρχίζουμε και βλέπουμε πράματα όταν ο κώδικάς μας μπει στο βρόγχο gtk_main (), ο οποίος είναι και ο κύριος βρόγχος του προγράμματός μας. Μετά από αυτή την εντολή τίποτε δε συμβαίνει.


Pygtk
Και ύστερα από την παραπάνω προτροπή ακολουθεί σε python. Η python είναι μια γλώσσα προγραμματισμού που δε χρειάζεται να μεταγλωττιστεί (interpreted και όχι compiled, ας με βοηθήσει κάποιος με την ελληνική ορολογία) Σε αυτή την περίπτωση θα χρειαστούμε επιπλέον το πακέτο pygtk.

Ανοίγουμε το τερματικό και πληκτρολογούμε python και μας περιμένει το γνωστό
>>>
Εδώ πληκτρολογούμε

>>>import pygtk
>>>import gtk

κι έτσι έχουμε εισάγει τις βιβλιοθήκες που χρειαζόμαστε. Μιας και στην python δε χρειάζεται να δηλώσουμε μεταβλητές απλώς δημιουργουμε το παράθυρό μας με

>>>window = gtk.Window(gtk.WINDOW_TOPLEVEL)

και το προβάλουμε με

>>> window.show()

Προφανώς ακόμη δεν εμφανίστηκε τίποτε στην οθόνη γιατί δε φτάσουμε στο κυρίως βρόγχο. Αυτό γίνεται με

>>>gtk.main_level()

Και πάλι το πρόγραμμά μας δεν έχει δυνατότητα τερματισμού εκτός από ctrl+c. Η δυνατότητα τερματισμού πραγματοποιείται με σύνδεση του συμβάντος με την αντίστοιχη εντολή.

Friday, 13 February 2009

sed

H sed είναι κι αυτή μια γλώσσα προγραμματισμού για μαζική επεξεργασία κειμένου. Ο όρος μαζική αναφέρεται στην αλλάγη για παράδειγμα μιας ακολουθίας γραμματων με μία άλλη σε πολλά αρχεία. Δε θέλουμε φυσικά να κάνουμε αυτή τη δουλειά για όλα τα αρχεία με το χερί, γι'αυτό και υπάρχουν αυτά τα εργαλεία που την αυτοματοποιούν.

Aς υποθέσουμε ότι θέλουμε να αλλάξουμε σε ένα αρχείο, χωρίς να το ανοίξουμε με κάποιο πρόγραμμα, όλες τις εμφανίσεις της λέξης foo σε man. To αρχικό αρχείο είναι το old και αποθηκεύουμαι τις αλλαγές στο new. Αυτό γίνεται πολύ απλά με την παρακάτω εντολή:

sed s/foo/man/ < old > new

awk

Η awk είναι μια ακόμη γλώσσα προγραμματισμού που χρησιμοποιείται συνήθως σε συνδυασμό με προγράμματα κελύφους. Σκοπός της είναι να διευκολύνει την αναζήτηση σε αρχεία για ένα συγκεκριμένο μόρφωμα (pattern). Μπορεί να χρησιμοποιηθεί είτε ως εντολή από το τερματικό:
awk 'source code' input-file1 input-file2
ή αν το πρόγραμμα είναι αρκετά μεγάλο να εκτελεστεί από ένα αρχείο:
awk -f program-file input-file1 input-file2 ...
Ένα απλό πρόγραμμα awk είναι το εξής:
awk '{ print }'
το οποίο τυπώνει ό,τι γράψετε στην οθόνη (όχι με ανεξίτηλο μαρκαδόρο γιατι δε θα σβήνει μετα με τίποτε).
Ένα πιο χρήσιμο πρόγραμμα θα μπορούσε να είναι το εξής:
ps aux | awk '/foo/ { print $2 }'
το οποίο τυπώνει τη δεύτερη στήλη της εντολής ps μόνο αν μία συγκεκριμένη γραμμή περιέχει την ακολουθία foo.

grep

Η εντολή grep είναι από τις πλέον ισχυρές εντολές στο linux. H χρήση της συνήθως συνδυάζεται με τους διαύλους (pipes). Σκοπός της είναι η αναζήτηση μιας ακολουθίας χαρακτήρων σε ένα κείμενο. Αλλά ας δούμε ένα παράδειγμα. To αποτέλεσμα της εντολής:

ps aux

είναι όλες οι δειργασίες που εκτελουνται στον υπολογιστή μας από όλους τους χρήστες και όπως φαντάζεστε είναι αρκετά μακροσκελές. Εμείς όμως ψάχνουμε το id μιας συγκεκριμένης διεργασίας, η οποία ξέρουμε ότι περιέχει το συνδυασμό γραμμάτων qti. Για να αναζητήσουμε αυτή τη διεργασία διοχετεύουμε το αποτέλεσμα της εντολής ps aux με ένα δίαυλο στην εντολή grep:

ps aux | grep qti


η οποία μετά αναζητεί το συνδυασμό χαρακτήρων qti και επιστρέφει μόνο εκείνες τις γραμμές που περιεχουν αυτό το συνδυασμό. Φυσικά η χρήση διαύλων δε περιορίζεται μόνο σε έναν:

ps aux | grep qti | grep wx


(Eίναι πολύ πιθανό η παραπάνω εντολές να μην επιστρέψουν τίποτε αν δεν υπάρχουν διεργασίες με τετοιους συνδυασμούς γραμμάτων στο όνομά τους.)

Thursday, 11 December 2008

Aλγόριθμος RSA

Ένας αλγοριθμος κρυπτογράφησης που χρησιμοποιείται στο ssh είναι ο rsa. Γι'αυτό θα προσπαθήσω να εξηγήσω πως λειτουργεί αυτός ο αλγόριθμος. Καταρχήν ας δούμε πως λειτουργεί η δημιουργία κλειδιού (η εντολή είναι ssh-keygen)

Αρχικά χρειαζόμαστε δύο μεγάλους πρώτους αριθμούς. Πρώτοι δηλαδή να διαιρούνται μόνο με τον εαυτό τους και τη μονάδα. Μεγάλοι για να είναι πιο δύσκολη η αποκρυπτογράφηση. Στο παράδειγμα όμως θα περιοριστούμε με μικρούς για να διευκολύνουμε τις πράξεις. Ας υποθέσουμε ότι έχουμε τους αριθμούς p = 19 και q = 7. Και οι δύο διαιρούνται μόνο με τον εαυτό τους και το 1.

Έπειτα υπολογίζουμε το γινόμενό τους n = p q = 19 * 7 = 133, o οποίος φυσικά δεν είναι πρώτος γιατί είναι το γινόμενο δύο άλλων αριθμών.

Το τρίτο βήμα είναι να υπολογίσουμε το γινόμενο φ(n) = (p-1)(q-1) = (19-1)*(7-1) = 18 * 6 = 108.

Μετά πρέπει να επιλέξουμε έναν αριθμό e, τέτοιο ώστε να είναι μεγαλύτερος του 1 και μικρότερος του φ(n) =108. Δηλαδή 1 < e < φ(n). Επιπλέον δεν πρέπει να έχει κοινά πολλαπλάσια με τον φ(n), δηλαδή με το 108. Γι'αυτό πρέπει να αναλύσουμε τον 108 στα πολλαπλάσιά του, 108 = 2 * 2 *3 * 3* 3. Άρα ο e δε μπορεί να είναι 2, 3, 4, 6, 12, 18, 27, 36, 54, 108 (ελπίζω να βρήκα όλους τους συνδυασμούς, αν κάνω λάθος διορθώστε με). Ας διαλέξουμε το 5 για να είμαστε σίγουροι. Το ε = 5 είναι το δημόσιο κλειδί (public key) που αποθηκεύεται ώς ~/.ssh/id_rsa.pub.

Tέλος, ψάχνουμε για έναν αριθμό d, τέτοιος ώστε αν πολλαπλασιάσουμε το d με το e και μετά διαιρέσουμε με το φ(n) το υπόλοιπο της διαίρεσης να είναι 1. Ένας τέτοιος αριθμός είναι το 65, γιατί 65*5=325 = 1 + 3*108 που αφήνει υπόλοιπο 1. Ο αριθμός d = 65 είναι το ιδιωτικό κλειδί (private key) που αποθηκεύεται ως ~/.ssh/id_rsa.

Monday, 8 December 2008

Αλλά τι είναι ένας υπολογιστής; ΙV

Στο τελευταίο μέρος αυτού του νήματος είδαμε τι είναι οι δείκτες, θέσεις μνήμης δηλαδή που δείχνουν σε μια άλλη θέση μνήμης--περιέχουν τη διεύθυνση της μνήμης αυτής. Εδώ θα δούμε πως μπορούν να χρησιμοποιηθούν οι δείκτες κατά τον προγραμματισμό, χωρίς να γράψουμε ούτε μία γραμμή κώδικα. Για το λόγο αυτό είναι απαραίτητο να εισηχθούν κάποιες καινούριες έννοιες οι οποίες είναι γνωστές και στα χρηματοοικονομικά, όπως ουρά αναμονής, first in first out (FIFO), last in first out (LIFO) και άλλα.

Πριν απ'όλα πρέπει όμως να εξηγήσουμε τί είναι οι αγωγοί ή δίαυλοι (pipes). Τους χρησιμοποιούμε καθημερινά κι όμως είναι ό,τι καλύτερο έχει συμβεί στην ιστορία του unix και των υπολογιστών γενικότερα. Ας δούμε μια απλή εντολή πιο αναλυτικά:
ps aux | grep ps
Η εντολή ps με τα ορισματα aux τυπώνει όλες τις διεργασίες που τρέχουν στον υπολογιστή από όλους τους χρήστες. Η εντολή grep ψάχνει για το συνδυασμό γραμμάτων ps. Το αποτέλεσμα θα είναι όλες εκείνες οι γραμμές της εντολής ps που περιέχουν το συνδυασμό γραμμάτων ps. Αυτό που συμβαίνει είναι το αποτέλεσμα της πρώτης εντολής να διοχετεύεται σαν είσοδος στην πρώτη. Αλλά πως διοχετεύεται; Στην πραγματικότητα δημιουργείται ένα είδος αρχείου--έχει κάποιες διαφορές από τα συνηθισμένα αρχεία--που ονομαζεται pipe. Στο αρχείο αυτό γράφονται τα αποτελέσματα της πρώτης εντολής και διαβάζονται από τη δεύτερη.

Αλλά πώς γράφονται και πώς διαβάζονται; Με ποιά σειρά; Κι εδώ ακριβώς μπαίνει στο παιχνίδι η ρευστομηχανική, τα χρηματοοικονομικά και η ακαταστασία σε κάθε γραφείο. Μιά στίβα από χαρτιά σε ένα γραφείο λειτουργεί ως εξής: βάζεις το πρώτο χαρτί, και έπειτα το επόμενο χαρτί το ακουμπάς πάνω στο προηγούμενο. Όταν θες να πάρεις κάτι παίρνεις το πάνω πάνω. (Υπάρχει και η αναζήτηση, αλλά την αφήνουμε για το μέλλον, είναι πιο πολύπλοκη.) Επειτα έχουμε ένα λάστιχο με νερό. Αν βάλουμε νερό στη μία ακρη τότε θα βγει από την άλλη, κι αν ρίξουμε κι άλλο νερό τότε θα βγεί από την άλλη άκρη μόνο αν το αρχικό νερό που βάλαμε έχει αδειάσει. Τέλος πάμε στη ΔΕΗ ή στον ΟΤΕ να πληρώσουμε τα χρέη μας και πληρώνουμε με τις ώρες στην ουρά. Όσο πιο νωρίς πάμε τόσο νωρίτερα θα εξυπηρετηθούμε, εκτός φυσικά κι αν κάποιος κλέψει. Όλα τα παραπάνω είναι παραδείγματα από ουρές που παρατηρούνται και εφαρμόζονται ακόμη και στους υπολογιστές. Το παράδειγμα του αγωγού που χρησιμοποιήσαμε παραπάνω είναι ένα κλασικό παράδειγμα FIFO, ό,τι δηλαδή μπαίνει πρώτο βγαίνει και πρώτο. Αντίθετα η στίβα πάνω στο γραφείο μας είναι ένα παράδειγμα LIFO, last in first out, γιατί ό,τι μπαίνει τελευταίο βγαίνει πρώτο.

Τι σημαίνει αυτό για τη μνήμη του υπολογιστή και τη διαχείρησή της από ένα πρόγραμμα; Ας πάρουμε το παράδειγμα της στίβας. Φυσικά το πρόγραμμα δε μπορεί να ξέρει εκ των προτέρων πόση μνήμη θα χρειαστεί (δε ξέρουμε εκ των προτέρων πόσα χαρτιά θα στιβάσουμε πάνω στο γραφείο μας). Ας υποθέσουμε ότι ένα χαρτί κατέχει μία θέση μνήμης. Τοποθετούμε το πρώτο χαρτί στο γραφείο μας. Έπειτα τοποθετούμε και ένα δεύτερο χαρτί πάνω στο γραφείο (τη μνήμη του υπολογιστή). Για να πούμε ότι κάνουμε μια στίβα, πρέπει να το βάλουμε πάνω στο άλλο. Αυτό σε γλώσσα υπολογιστών σημαίνει ότι χρειαζόμαστε και μία ακόμη θέση, ένα δείκτη, που δείχνει το χαρτί που βρίσκεται από πάνω. Φυσικά ο δείκτης του τελευταίου χαρτιού δε θα δείχνει πουθενά. Έτσι σε κάθε καινούριο χαρτί που προστείθεται στη στίβα μας πρέπει να δείχνει το προηγούμενο.

Κάπως έτσι λειτουργούν και οι αγωγοί στο linux, δημιουργούν ένα αρχείο, τα δεδομένα του οποίου επεξεργάζονται από τη δεύτερη εντολή με τη σειρά που γράφτηκαν στο αρχείο. Οι αγωγοί είναι FIFO, σε αντίθεση με τις στίβες που είναι LIFO.

Την ίδια λογική μπορούμε να την επεκτείνουμε και σε άλλα φυσικά παραδείγματα, όπως τη δενδρική δομή. Όλοι έχουμε παρατηρήσει ένα δέντρο με το κορμό, από τον οποίο βγαίνουν δυο-τρία κεντρικά κλαδιά, τα οποία με τη σειρά τους γεννάνε δικά τους παρακλάδια, και συνεχίζεται μέχρι τα φύλλα. Έτσι και στους υπολογιστές έχουμε μία θέση μνήμης, τον κορμό, και δύο δείκτες που δείχνουν σε δύο κλαδιά. Το κάθε κλαδί με τη σειρά του έχει μία θέση μνήμης και δύο δείκτες που δείχνουν στα παρακλάδια, κοκ.

Φυσικά για να λειτουργήσουν όλα αυτά χρειαζόμαστε και τις διεργασίες που προσθέτουν ή αφαίρουν, χαρτιά από τη στίβα μας, ή κλαδιά από τη δενδρική δομή.

Για να κάνουμε τα πράματα ακόμη πιο ενδιαφέροντα μπορούμε να έχουμε μία κυκλική δομή όπου το τελευταίο στοιχείο δείχνει στο πρώτο ή ακόμη πιο πολύπλοκες δομές όπου ένα παρακλάδι ενός δέντρου δείχνει σε ένα κλαδί σε κάποιο άλλο σημείο του δέντρου ή (η φαντασία σας μπορεί να οργιάσει) δύο δέντρα όπου ένα κλαδί του πρώτου δέντρου δείχνει σε ένα παρακλάδι του δευτερου (μήπως αυτό δε συμβαίνει σε οργανισμού όπως κισσός, δεν είμαι και βιολόγος αλλά έψαχνα να βρώ ένα φυσικό ανάλογο.)

Thursday, 27 November 2008

Αλλά τι είναι ένας υπολογιστής; ΙΙΙ

Πώς αποθηκεύονται οι αριθμοί σε ένα ηλεκτρονικό κύκλωμα που καταλαβαίνει μόνο 0 και 1; Παραπάνω είδαμε πως περιγράφονται οι ακέραιοι (1, 2, 3, ...) με τη βοήθεια πολλών λαμπτήρων, αλλά τι γίνεται με τον αριθμό 3,14 (τυχαία τον επέλεξα, δεν έχει να κάνει τίποτε με το π). Εδώ τα πράματα γίνονται λίγο πιο πολύπλοκα και γι'αυτό καθιερώθηκαν κάποια πρότυπα που διευκολύνουν τη ζωή των υπολογιστών. Καταρχήν θα γράψουμε τον αριθμο 3,14 ως εξής: + 0,314 * 10**1. (Το σύμβολο ** δηλώνει εκθέτη επηρεασμένος από τη FORTRAN, δηλαδή 10**1=10, 10**2=100, 10**3=1000 κ.ο.κ) Το πρόσημο μπορεί να είναι + ή -, αρα μπορεί να περιγραφεί με μία λάμπα, σβηστή/ανοιχτή. Το 0, αποφασίσαμε να είναι το ίδιο για όλους τους αριθμούς, άρα δε χρειάζεται να το αποθηκεύσουμε. Έπειτα μετατρέπουμε τον αριθμό 314 σε δυαδική μορφή, όπως περιγράφεται παραπάνω, δηλ. 100111010. Το 10** είναι κι αυτό μέσα στην τυποποίησή μας. Και μετά αποθηκεύουμε το 1. Έτσι χρειαζόμαστε μία λάμπα για το πρόσημο, ένα σύνολο από λάμπες για τον αριθμό μετά την υποδιαστολή (για συντομία θα το λέμε mantissa), και μετά σύνολο από λάμπες για τον εκθέτη. Όσο μεγαλύτερο είναι τα σύνολο (η μνήμη δηλαδή) για τον αριθμό μετά την υποδιαστολή τόση μεγαλύτερη ακρίβεια μπορούμε να επιτυχουμε. Όσο μεγαλύτερο είναι τα σύνολο (η μνήμη δηλαδή) για τον εκθέτη τόσο μεγαλύτερους αριθμούς μπορούμε να αποθηκεύσουμε. Αυτή είναι ουσιαστικά η διαφορά μεταξύ float και double στη C αλλά και σε πολλές γλώσσες προγραμματισμού.

Πώς κάνουμε τώρα πράξεις με αυτό το πολύπλοκο κατασκεύασμα; Όπως θα την κάναμε και με το χέρι. Άς πάρουμε την πρόσθεση. Πρώτα θα συγκρίναμε τον εκθέτη, έπειτα θα μετακινούσαμε την υποδιαστολή στην κατάλληλ θέση, θα προσθέταμε και τέλος θα φέρναμε το αποτέλεσμα στην τελική μορφή. Αυτό κάνει και ο επεξεργαστής όταν έχει να προσθέσει δύο αριθμούς. Η όλη διαδικασία λέγεται αναφέρεται ως floating point arithemic. Και αυτός είναι ουσιαστικά ο τρόπος να συγκρίνουμε δύο επεξεργαστές. Πόσες πράξεις μπορούνε να κάνουν το δευτερόλεπτο (FLOPS=Floating Point Operations Per Second)

Ας υποθέσουμε τώρα ότι έχουμε μια ταινία (μαγνητική όπως οι παλιές), η οποία είναι χωρισμένη σε τετραγωνα. Σε κάθε τετράγωνο χωράει ένας δυαδικός αριθμός με 4 ψηφία, ας πούμε. Τότε ο αριθμός παραπάνω θα χρειάζεται ένα τετραγωνο για την αποθήκευση του προσήμου (0000), 6 τετράγωνα για την αποθήκευση της mantissa (000 0000 0000 0001 0011 1010) και ένα τετράγωνα για τον εκθετη (0001), σύνολο 8. Αν έχουμε δηλαδή ένα array (a[10] στη C) με 10 τέτοιους αριθμούς, τότε αυτοί θα αποθηκευτούν διαδοχικά στα 8x10 τετράγωνα, θέσεις μνήμης δηλαδή.

Mέχρι στιγμής προϋποθέτουμε ότι οι δύο αριθμοί βρίσκονται στη μνήμη. Σε ποιά μνήμη όμως; Καταρχήν υπάρχει ο σκληρός δίσκος, μπορεί να χρησιμεύσει ως εικονική μνήμη (virtual memory) αλλά είναι πολύ αργός. Έπειτα είναι η RAM, ένα ενδιάμεσο βήμα με μικρότερη χωρητικότητα, αλλά ελαφρώς πιο γρήγορη από το σκληρό δισκό (ναι καλά διαβάσατε, ελαφρώς πιο γρήγορη σε σχέση με αυτό που ακολουθεί). Έπειτα έχουμε την cache (υπάρχει σε δύο επίπεδα L2 και L1) η οποία είναι σαφώς γρηγορότερη αλλά και μικρότερα. Τέλος υπάρχει το registry, που είναι ουσιαστικά ενσωματωμένο στον επεξεργαστή και χωράει ίσα ίσα μερικές μεταβητές (βλ. register της C).

Περνάμε τώρα στο cache mapping. To παραπάνω array χωράει στη μνήμη RAM χωρίς κανένα πρόβλημα. Αλλά ας υποθέσουμε (τα νούμερα εδώ είναι για λόγους του παραδείγματος μόνο, στην πραγματικότητα είναι μεγαλύτερα) ότι η μνήμη cache έχει μόνο 40 τετράγωνα. Tότε αυτό που θα κάνει ο υπολογιστής, σε ένα βρόγχο για παράδειγμα, είναι να φορτώσει τα 20 πρώτα μέλη του array μας και μετά τα επόμενα 20. Ένα πρόγραμμα αρχίζει και γίνεται αργό όταν δεν είναι καλά σχεδιασμένο και την ίδια στιγμή χρειάζονται τα a[3] και a[8] για μία διεργασία.

Αν αριθμήσουμε την ταινία μας από 1 μέχρι 80 και πάει λέγοντας, τότε μπορούμε να αναθέσουμε σε κάθε αριθμό και μία διεύθυνση. Το τρίτο στοιχείο του array ξεκινάει στη θέση 17 (2*8+1) στο δυαδικό 0001 0001. Αν αποθηκεύσουμε αυτόν τον αριθμό στα τετράγωνα ας πούμε 126-127 τότε έχουμε τη διεύθυνση του a[3]. Αυτό το ονομάζουμε δείκτη (pointer) γιατί δείχνει στη διεύθυνση κάποιου άλλου στοιχείου. (Να με συγχωρέσουν οι προγαμματιστές C για τον "ανορθόδοξο" τρόπο αρίθμησης)

Thursday, 20 November 2008

Screen

Σιγουρα θα έχει τύχει να θέλετε να συνδεθείτε σε έναν απομακρυσμένο υπολογιστή, π.χ. με shh, να ξεκινήσετε μια εντολή από τη γραμμή εντολών, να αποσυνδεθείτε και μετά να συνδεθείτε από κάποιον άλλο υπολογιστή για να δείτε τα αποτελέσματά της. Κάτι τέτοιο είναι δυνατό με τη χρήση του προγράμματος screen, το οποίο πρέπει να είναι εγκατεστημένο φυσικά στον απομακρυσμένο υπολογιστή. Η εγκατάσταση γίνεται όπως πάντα από τη γραμμή εντολών:
sudo apt-get install screen
H τυπική χρήση της εντολής είναι πρώτα να δημιουργήσουμε μια "οθόνη", να εκκινήσουμε εκεί τα προγράμματά μας, να "αποκολλήσουμε" (detach) την οθόνη, και έπειτα να ξανασυνδεθούμε από κάποιο άλλο μέρος του πλανήτη στην ίδια "οθόνη". Πληκτρολογώντας απλά
screen
δημιουργείται μια οθόνη με ένα τυχαίο id. Έπειτα πατάμε Enter ή Space όπως μας λέει η οθονη και είμαστε σε ένα νέο κέλυφος. Εδω μπορούμε να εκκινήσουμε μια οποιαδήποτε διεργασία. Για να αποκολλήσουμε την οθονη στην οποία βρισκόμαστε πληκτρολογούμε Ctrl+A+D (εχοντας πατημένο το ctrl, χωρίς τα + φυσικά)Τώρα είμαστε στο προηγούμενο τερματικό απ' όπου ξεκινήσαμε. Για να δούμε πόσες οθόνες υπάρχουν, πληκτρολογούμε:
screen -ls
και μπορούμε να δούμε τα ονόματα των "οθονών" καθώς και αν είναι αποκολλημένες ή όχι (Detached-Attached).
Για να δώσουμε ένα δικό μας όνομα, πχ. myscreen, στην οθόνη πληκτρολογούμε:
screen -R myscreen
Aν μια οθόνη είναι αποκολλημένη τότε μπορούμε να ανοίξουμε ένα άλλο κέλυφος, το οποίο μπορεί να προέλθει και από ssh, και πληκτρολογούμε για παράδειγμα:
screen -r myscreen
Eτσι επανερχόμαστε σε ότι κάναμε προηγουμένως. Φυσικά δε θα κρατήσει στη μνήμη όλα τα αποτελέσματα του προγράμματος που εκκινήσαμε στην οθονη. Για να το πετυχουμε και αυτό, πρέπει να κάνουμε χρήση της εντολής script. Οι οθόνες τερματίζονται όπως κάθε κέλυφος με exit ή ctrl+D. Περισσότερες λεπτομέρειες μπορείτε να βρείτε στο εγχειρίδιο:
man screen

Saturday, 30 August 2008

Permissions III

Ένα σημείο το οποίο χωράει συζήτηση είναι το δικαίωμα ανάγνωσης (r). Όταν κάποιος άλλος χρήστης έχει δικαίωμα ανάγνωσης μόνο, σημαίνει ότι μπορεί να διαβάσει το αρχείο αλλά όχι να το τροποποιήση. Να διαβάσει όμως σημαίνει όχι απλώς να το ανοιξει με έναν editor και να το διαβάσει, αλλά να το αντιγράψει κι όλας, με την εντολή cp για παράδειγμα. Φυσικά το νέο αρχείο θα έχει ως ιδιοκτήτη το νέο χρήστη. Αυτό δημιουργία κάποια ανασφάλεια στους νέους χρήστες, αλλά δυστυχώς ή ευτυχώς έτσι είναι. Δεν είναι ούτε bug ούτε feature. Πολλές μεγάλες δισκογραφικές εταιρίες κάνουν έρευνα ώστε να μπορεί κάποιος να διαβάζει κάτι χωρίς να μπορεί να το αντιγράψει αλλά ανεπιτυχώς θα έλεγα. Οπότε αν θέλετε να μη μπορεί κάποιος να αντιγραψει τα αρχεία σας θα πρέπει να μην τους δώσετε δικαιώματα ανάγνωσης.

Μια δεύτερη επισήμανση είναι οι φάκελοι. Για να μπορέσει κανείς να "μπει" μέσα σε ένα φάκελο πρέπει να έχει δικαίωμα εκτέλεσης του φακέλου.

Αν θέλουμε να αναφερθούμε σε όλους τους χρήστες (u, g και ο) τότε μπορούμε να γράψουμε a (all) δηλαδή
chmod a+w myfile
δίνει σε όλους δικαίωμα τροποποίησης.

Ακόμη μία άσκηση: Πώς μπορούμε να δημιουργήσουμε ένα φάκελο που να λειτουργεί σαν γραμματοκιβώτιο όπου όλοι μπορούν να γράψουν ένα αρχειό (να στείλουν ένα γράμμα) αλλά να μόνο ο ιδιοκτήτης να μπορεί να δεί το γραμματοκιβώτιό του. Το γράμμα μπορεί να το καταστρέψει ο αποστολέας; Ο παραλήπτης;

Permissions II

Και τώρα η συνέχεια!

Η σύνταξη της εντολής chgrp είναι:
chgrp mygroup myfile
όπου mygroup είναι η ομάδα στην οποιά θα αλλάξει το αρχείο myfile. Mερικές επιλογές είναι -R η οποία αλλάζει και τις ομάδες στους υποφακέλους του myfile, αν υπάρχουν.

Αντίστοιχα, η σύνταξη της εντολής chown είναι:
chown owner myfile
όπου owner είναι o καινούριος ιδιοκτήτης στον οποιά θα ανηκει το αρχείο myfile. Mερικές επιλογές είναι -R η οποία αλλάζει και τους ιδιοκτήτες στους υποφακέλους του myfile, αν υπάρχουν.

Η εντολή chmod αλλάζει τα δικαιώματα ως εξής:
chmod mode myfile
όπου mode είναι τα νέα δικαιώματα του αρχείου myfile. Oι επιλογές του mode δίνονται με ένα γράμμα που δείχνει ποιον αφορά η αλλάγη (u, g, o), επειτα + για να προσθέσουμε δικαιώματα ή με - για να τα αφαιρέσουμε και έπειτα ακολουθουν τι δικαιώματα θέλουμε να δώσουμε ή να αφαιρέσουμε (r,w,x).

Με μερικά παραδείγματα θα γίνει πιο κατανοητό.
ls -l
-rw-r--r-- 1 dp staff 0 Aug 27 10:01 myfile
έχουμε ένα απλό αρχείο με δικαιώματα αναγνωσης και τροποποίησης από τον ιδιοκτήτη (dp), αναγνωσης από την ομάδα (staff) και αναγνωσης από όλους τους άλλους. Η εντολή:
chmod u+x myfile
δίνει στον ιδιοκτητη το δικαίωμα να το εκτελεσει το αρχειο. Φυσικά αν δεν είναι bash script, ή εκτελέσιμο πρόγραμμα ή python script, κτλ. θα βγάλει σφάλμα αν πάμε να το εκτελέσουμε με
./myfile
Aλλά υποτίθεται ότι ξέρουμε σε ποια αρχεία δίνουμε το δικαίωμα της εκτέλεσης. Mε ls -l
-rwxr--r-- 1 dp staff 0 Aug 27 10:01 myfile*
βλέπουμε στην πρώτη τριαδα το x. Aναλογα με τις ρυθμίσεις του κελύφους bash θα αλλάξει και το χρώμα του myfile (σε μενα βάζει ένα αστεράκι). Η εντολή:
chmod u-x myfile
το επαναφέρει στην αρχική του κατάσταση.
chmod go+w myfile
θα δώσει δικαιώματα τροποποίησης στην ομάδα staff και σε όλους τους άλλους. Το αποτελεσμα της ls -l θα είναι τότε:
-rwxrw-rw- 1 dp staff 0 Aug 27 10:01 myfile*
στη δεύτερη και την τρίτη στήλη θα υπάρχει και w.
chmod o-wr myfile
θα αφαιρέσει το δικαίωμα τροποποιησης και αναγνωσης από όλους όσους δεν ανήκουν στην ομάδα staff.

Υπάρχει και ένας δεύτερος τρόπος περιγραφης των δικαίωματων, κάπως πιο απόκρυφος ο οποίος χρησιμοποιείται και κάπως παραλαγμένος στην umask (Θα φτάσουμε κι εκεί.) Την κάθε τριάδα μπορούμε να την δούμε σαν ένα δυαδικό αριθμό που αποτελείται από bits τα οποία μπορεί να είναι 0 ή 1. Όταν υπάρχει ένα δικαίωμα το αντίστοιχο bit είναι 1, όταν δεν υπάρχει είναι 0. Η τριάδα r-- θα είναι ο αριθμό 100 στο δυαδικό σύστημα, τον οποίο αν το μετατρέψουμε στο δεκαδικό θα είναι ο 1x2**2+0x2**1 +0x2**0 (** σημαίνει ύψωση σε δύναμη) δηλαδή 4. Αντίστοιχα η τριάδα rw- αντιστοιχεί στο δυαδικό αριθμό 110 ή στον δεκαδικό 6. Αν θέλουμε τώρα να δώσουμε τα δικαιώματα rw-r--r-- σε ένα αρχείο θα δίναμε την εντολή:
chmod 644 myfile
Άσκηση: Ποιο θα είναι το αποτέλεσμα της εντολής;
chmod 755 myfile

Permissions

Τα δικαιώματα (permissions) είναι ένα από τα βασικά χαρακτηριστικά των συστημάτων unix γενικότερα, που επιτρέπει τους χρήστες να ανταλλάσουν αρχεία ή να περιορίζουν την πρόσβαση τρίτων. Ας ανοίξουμε όμως ένα τερματικό από Αpplications > Accessories > Terminal για να δούμε ακριβώς τι συμβαίνει. Είμαστε λογικά στο αρχικό κατάλογο (/home/user όπου user το ονομα χρήστη σας) Πληκτρολογούμε:
ls -l
H εντολή αυτή μας εμφανίζει τα περιεχόμενα του καταλόγου μαζί με χίλιες δυο άλλες άχρηστες πληροφορίες.

Η πρώτη στηλη μπορεί να είναι d ή -, d για φάκελος (directory), - για απλό αρχείο.
Κάθε αρχείο, κι όταν λέω αρχείο εννοώ και φακέλους, έχει ορισμένα χαρακτηριστικά, όπως σε ποιον ανήκει το αρχείο, σε ποια ομάδα ανήκει, ποιος έχει δικαίωμα να το διαβάσει, να το τροποποιήσει ή να το εκτελέσει. Η επόμενες 9 στήλες είναι συνδυασμοί των r,w,x,- έπειτα ακολουθεί ένας αριθμός, κι εκεί βλέπεται το όνομα του χρήστη σας δύο φορές. Η πρώτη εμφάνιση του user συμβολίζει τον ιδιοκτήτη του αρχείου (owner). H δεύτερη εμφάνιση την ομάδα (group). Oι 9 στήλες που περάσαμε είναι 3 συνδυασμοί των 3. Οι πρώτοι 3 συνδυασμοί αναφέρονται στα δικαιώματα του χρήστη. Η δεύτερη τριάδα αναφέρεται στα δικαιώματα της ομάδας και η τελευταία τριάδα στα δικαιώματα των άλλων (οthers, βλ. ανέκδοτο: εσύ με ποιούς είσαι με μας ή με τους άλλους; )

r σημαίνει δικαιώματα ανάγνωσης (read). w σημαίνει δικαιώματα τροποποίησης (write). x σημαίνει δικαιώματα εκτέλεσης (execute). Οποτε αν δούμε το συνδυασμό -rw-r--r-- σημαίνει ότι το αρχείο είναι απλό αρχείο και όχι φάκελος, ο χρήστης στον οποίο ανήκει το αρχείο έχει δικαιώματα να το διαβάσει και να το τροποποιήσει, αλλά όχι να το εκτελέσει. Οι χρήστες που ανήκουν στην ομάδα έχουν δικαίωμα μόνο ανάγνωσης και οι άλλοι έχουν επισης δικαίωμα μόνο ανάγνωσης.

Ο αριθμός που μας διέφυγε σημαίνει πόσα αρχεία περιλαμβάνει το αρχείο μας (Τι αριθμό θα έχει ένα αρχείο με - μπροστα κι όχι d; )

Φυσικά όλα αυτά τα δικαιώματα μπορούν να αλλάξουν. Μερικές χρήσιμες εντολές είναι η chgrp, chown, chmod. H chgrp αλλάζει την ομάδα του αρχείου. Η chown αλλάζει τον ιδιοκτήτη του αρχείου. Και η chmod αλλάζει τα δικαιώματα. Φυσικά για να αλλάξουν αυτά πρέπει να είμαστε ιδιοκτήτες του αρχείου.

Αντιμετώπιση προβλημάτων

Τι κάνουμε όταν:
  • έχει κολήσει το γραφικό περιβάλλον

    ctrl+alt+backspace

    Επανεκκινεί το xserver. Στις περισσότερες περιπτώσεις ίσως αρκεί να κάνουμε μόνο αυτό.
  • έχει κολήσει το γραφικό περιβάλλον και δεν επανέρχεται με ctrl+alt+backspace

    ctrl+alt+f1

    Μας βγάζει σε μία γραμμή εντολών όπου δίνουμε όνομα και κωδικό χρήστη. Από εκεί μπορούμε να κάνουμε τα πάντα :D Αυτό που θα θέλουμε αν φτάσουμε σε αυτό το σημείο είναι να κλείσουμε ή να κάνουμε επανεκκίνηση τον υπολογιστή. O τερματισμός γίνεται με την εντολή:

    sudo shutdown -h now

    ενώ η επανεκκίνηση με:

    sudo shutdown -r now
  • δεν ανταποκρίνεται το πληκτρολόγιο

    ctrl+alt+PrintScreen+R

    Θα μας δώσει το πληκτρολόγιο πάλι υπο τον έλεγχό μας. Τότε μπορούμε να πάμε στην αρχή της λίστας και να δοκιμάσουμε τα δύο πρώτα βήματα.
  • δεν ανταποκρίνεται το πληκτρολόγιο και το παραπάνω βήμα δεν έχει αποτελέσματα

    ctrl+alt+PrintScreen+REISUB

    Τερματίζει τον υπολογιστή σωστά.

ΠΡΟΣΟΧΗ: Σε καμία περίπτωση δε σβήνουμε τον υπολογιστή αποσυνδέοντας την τροφοδοσία (βγάζοντας τον απο την μπριζα, ή σβήνοντας το διακόπτη). Είναι ότι χειρότερο μπορούμε να κάνουμε για τα δεδομένα μας.

Wednesday, 20 August 2008

xorg.conf

Eνα βασικό αρχείο ρυθμίσεων του X-server, της υπηρεσίας δηλαδή γραφικών σε συστήματα linux, είναι το /etc/X11/xorg.conf
Χωρίζεται σε διάφορα sections για καθε συσκευή. Καλό είναι να ξέρουμε τι κάνει το κάθε section, ώστε να μπορούμε να το προσαρμόζουμε κατά βούληση. Πάντα πριν από κάθε αλλαγή κρατάμε ένα αντίγραφο ασφαλείας:
cp /etc/X11/xorg.conf ~/Desktop
Mία αναλυτική περιγραφή του αρχείου μπορεί να βρεθεί εδώ: http://www.x.org/archive/X11R6.8.0/doc/xorg.conf.5.html
Οι επιλογές που επηρεάζουν τα γραφικά είναι Device, Monitor, Screen. Φυσικά δεν είναι οι μόνες.

Device
Πρέπει να έχει το λιγότερο ένα section για να λειτουργήσει η κάρτα γραφικών. Μπορεί όμως να περιλαμβάνει και παραπανω. Η δομή είναι η εξής:
Section "Device"
Identifier "name"
Driver "driver"
entries
...
EndSection
Τα πεδία Identifier και Driver είναι απαραίτητα. Το πεδίο Identifier δηλώνει το μοναδικό όνομα της συσκευής, που θα χρειαστεί παρακάτω. Το πεδίο Driver δηλώνει τον οδηγό που θα χρησιμοποιηθεί. Για nvidia κάρτες με κλειστούς οδηγούς αυτό μπορεί να είναι "nv" για τους παλιούς οδηγούς, ή "nvidia" για τους καινουριους. Οι οδηγοί πρέπει να είναι εγκατεστημένη για να είναι έγκυρη αυτή η επιλογή.

Monitor
Πρέπει να έχει το λιγότερο ένα section για να λειτουργήσει η οθόνη. Μπορεί όμως να περιλαμβάνει και παραπανω. Η δομή είναι η εξής:
Section "Monitor"
Identifier "name"
entries
...
EndSection
Τo πεδίo Identifier είναι απαραίτητo. Το πεδίο Identifier δηλώνει το μοναδικό όνομα της συσκευής, που θα χρειαστεί παρακάτω. Εδώ καθορίζεται η αναλυση της οθονης, συχνότητα ανανέωσης και άλλα.

Screen
Εδώ γίνεται ένας συνδυασμός Device και Monitor. Tα υποχρεωτικά πεδία είναι Identifier, Device, Monitor. Φυσικά για να χρησιμοποιηθεί ένα Device πρέπει προηγουμένως να έχει οριστεί. Το ίδιο και για το Monitor.

Monday, 18 August 2008

Πώς στήνεται ένα cluster;

ΠΡΟΣΟΧΗ: Αυτά που ακολουθούν είναι για γερά νεύρα. Μπορεί να περιέχουν λάθη, ασάφειες και ατέλειες ή απλώς να μην ισχύουν για όλα τα συστήματα. Δεν ευθύνομαι για τυχόν λάθη ή βλάβες που θα δημιουργηθούν. Ακολουθήστε με δική σας ευθύνη.

1. Εισαγωγή

Ένα cluster είναι ένα δίκτυο από υπολογιστές, σχεδιασμένοι να λειτουργούν από κοινού ώστε να λύσουν ένα πρόβλημα. Clusters χρησιμοποιούνται συνήθως αλλά όχι μόνο σε τομείς της υπολογιστικής μηχανικής, φυσικής, κρυπτογραφίας, δημιουργίας ταινιών κ.α. αλλά και για οποιαδήποτε εφαρμογή απαιτεί πολλη υπολογιστική ισχύ. Θα μπορούσε να χρησιμοποιηθεί και ως desktop αλλά ένα έτοιμο desktop κάνει καλύτερα τη δουλειά και με λιγότερο κόπο. Η ιδέα πισω από το parallel computing είναι η εξής: χωρίζω το πρόβλημά μου σε μικρότερα υποπροβλήματα τα οποία λύνονται πιο γρήγορα σε έναν υπολογιστή και έπειτα ανασυνθέτω τη λύση από τα επιμέρους στοιχεία. Για να τρέξει ένα πρόγραμμα σε ένα cluster πρέπει να προγραμματιστεί σε mpi (υπάρχουν βιβλιοθήκες τουλάχιστον για fortran, C, C++ ). Η μετατροπή ενός υπάρχοντος προγράμματος είναι πολύ δύσκολη και είναι προτιμότερο να ξαναγραφεί από την αρχή, μιας και η αρχή λειτουργίας είναι τελείως διαφορετική.

Δύο πακέτα που περιλαμβάνουν σχεδόν όλα όσα χρειαζόμαστε είναι το oscar και το rocks. Το oscar εγκαθίσταται σε ένα υπάρχον λειτουργικό - υποστηρίζει fedora, mandriva, suse, redhat, scientific linux, centos - ενώ το rocks εγκαθιστά και περιλαμβάνει το red hat. Είναι φυσικά δυνατόν να στηθεί ένα cluster πάνω σε οποιαδήποτε διανομή, αλλά αυτά είναι που διατίθενται έτοιμα και λειτουργούν με τον ελαχιστο κόπο.

Αυτό το μέρος θα ασχοληθεί με το καθαρά τεχνικό κομμάτι. Δηλαδή φυσική συναρμολόγηση του cluster. Έπειτα θα ακολουθήσει η εγκατάσταση του λειτουργικού, με όλα τα απαραίτητα προγράμματα και βιβλιοθήκες. Προς το παρόν αυτός ο οδηγός θα ασχοληθεί μόνο με red hat ως λειτουργικό. Τέλος θα δωθεί μια μικρή εισαγωγή σε προγραμματισμό με mpi.

2. Ασφάλεια

Πριν τη δημιουργία ενός cluster είναι απαραίτητο να γνωρίζουμε που βρίσκονται οι ασφάλειες της ηλεκτρικής εγκατάστασης. Επίσης πρέπει να ξέρουμε αν η ηλεκτρική μας εγκατάσταση αντέχει την ισχύ που θα εγκατασταθεί. (Μπορεί με 2 υπολογιστές να είναι αμελητέα, αλλά με 4 αρχίζουν και σοβαρεύουν τα πράματα.) Πρέπει επίσης να ξέρουμε ότι το σύστημα θα παραγει θερμότητα και το καλοκαίρι στην Ελλάδα είναι αρκετά επιφορτισμένο. Οπότε καλό είναι να σκεφτούμε και λίγο το περιβάλλον. (Εγω τα δοκιμάζω όλα αυτά κάπου στην κεντρική Ευρώπη με μέγιστη θερμοκρασία 25 βαθμούς.)

3. Προαπαιτούμενα

Τι θα χρειαστεί (ελάχιστα προαπαιτούμενα);

1 υπολογιστής (από δω και πέρα θα ονομάζεται master) με:
* 2 κάρτες δικτύου
* 1 GB ram
* 20 GB σκληρό δίσκο
* cdrom

2 υπολογιστές (από δω και πέρα θα ονομάζονται slave, και μπορούν να είναι και περισσότεροι) με:
* 1 κάρτα δικτύου
* 1 GB ram
* 20 GB σκληρό δίσκο
* cdrom ή PXE κάρτα δικτύου (με cdrom είναι πιο εύκολα)

1 ethernet switsch

4 καλώδια δικτύου ethernet

1 πολύμπριζο με διακόπτη (αν η μπρίζα του τοίχου δεν αντέχει την ισχύ τότε θα πρέπει να χρησιμοποιηθούν περισσότερες μπρίζες)

Οθόνη, πληκτρολόγιο, ποντικί είναι απαραίτητα μόνο για την αρχική εγκατάσταση. Έπειτα η διαχείρηση του cluster θα γίνεται απομακρυσμένα από το τοπικό δίκτυο (αν υπάρχει). Σε περίπτωση που δεν υπάρχει τοπικό δίκτυο τότε χρειάζονται μόνο στον master.

Η παρακάτω εγκατάσταση θα σβήσει όλα τα δεδομένα των υπολογιστών.

4. Συναρμολόγηση

Η βασική διάταξη που θα χρησιμοποιηθεί είναι όλοι οι υπολογιστές του cluster συνδέονται με όλους. Αυτό θα γίνει στο ethernet switch. Eπιπλέον ο master με τη δεύτερη κάρτα δικτύου θα συνδεθεί στο εξωτερικό τοπικό δίκτυο. Υπάρχουν φυσικά και άλλοι τρόποι συνδεσμολογίας, που για πολλούς υπολογιστές ελαχιστοποιούν τη χρήση καλωδιών και ethernet switch αλλά δε θα ασχοληθούμε με αυτούς.


Bιβλιογραφία
1. High Performance Linux Clusters: with OSCAR, ROCKs, openMosix & MPI, J. D. Sloan
2. Beowulf
3. Oscar
4. Rocks

Thursday, 14 August 2008

Αλλά τι είναι ένας υπολογιστής; ΙΙ

Περνώντας ένα επίπεδο παραπάνω από αυτές τις λογικές πύλες μπορούν να φτιαχνούν πιο πολύπλοκα ηλεκτρονικά εξαρτήματα. Οι αγωγοί που συνδέουν τις ηλεκτρονικές συσκευές μεταξύ τους και μεταφέρουν δεδομένα από τη μία στην άλλη λέγονται buses. Aν υποθέσουμε ότι χρειαζόμαστε να συνδέσουμε 3 συσκευές μεταξύ τους τότε χρειάζονται 3 αγωγοί που συνδεουν κάθε συσκευή με όλες τις άλλες. Με 4 συσκευές τότε ο αριθμός των αγωγών είναι 6, για 5 συσκευές χρειαζόμαστε 10 αγωγούς κ.τ.λ. Μια απλή τεχνική να μειωθεί το πλήθος των αγωγών είναι κάθε συσκευή να έχει τον κωδικό της, όλες οι συσκευές να συνδεθούν σε σειρά και στην αρχή των δεδομένων να υπαρχει ο κωδικός της κάθε συσκευής. Έτσι όλα τα δεδομένα περνάνε με τη σειρά από όλες τις συσκευες αλλά μόνο η συσκευή με το σωστό κωδικό δεχεται τα δεδομενα. Υπ'όψην ότι τα δεδομένα μπορεί να είναι όχι "απλά δεδομένα" αλλά κάποιο σύνολο οδηγιων που πρέπει να εκτελέσει η κάθε συσκευή.

Τι συμβαίνει όμως στην περίπτωση που ένας αγωγός πάθει βλάβη; Τότε όλο το σύστημα θα πάψει να λειτουργει. Στην περίπτωση αυτή πρέπει να υπάρχουν εφεδρικοί αγωγοί, αλλά πόσοι; Για 3 αγωγους είπαμε ότι χρειάζονται 3 αγωγοι, ενω αν χρησιμοποιήσουμε την τεχνικη διέυθυνσης τότε μειωνονται στους 2. Είναι εύκολο να δει κανεις ότι με 3 αγωγους όμως αν συμβεί το πολύ σε έναν αγωγό βλάβη τότε το σύστημα μπορεί να συνεχίσει να λειτουργεί. Παρόμοιες τεχνικές έχουν αναπτυχθεί και για πιο πολύπλοκα συστήματα.

Το πιο βασικό στοιχειo μνήμης είναι το register (καταχωρητής). Οι μνήμες αυτές είναι πολύ μικρές σε χωρητικότητα αλλά η ταχύτητα προσπέλασης τους είναι πολύ μεγάλη και είναι ενσωματωμένες στον επεργαστή. (Στους προγραμματιστές C είναι ίσως γνωστή η τεχνική να τοποθετούν μια μεταβλητή που θα χρησιμοποιηθεί πολλές φορές σε register για να αυξηθεί η ταχύτητα του προγράμματος.)

Εχοντας αυτά ως δομικά στοιχεία μπορούμε τώρα να γράψουμε ένα πρόγραμμα. Το σύνολο οδηγιών (instruction set) δεν είναι τίποτε άλλο από συνδυασμούς 4 βασικών οδηγιών - πρόσθεση, αφαιρεση, φορτωση, αποθηκευση δυαδικών αριθμών. Στις πρώτες assembly γλώσσες οι δυνατότητες δεν ήταν πολλές παραπάνω από αυτές τις 4. Καταρχήν χρειάζεται μια μνήμη για να αποθηκευτούν αυτές οι οδηγίες, ο καταχωρητης, και οι οδηγίες αυτές εκτελούνται από τον επεξεργαστή. Aς υποθέσουμε ότι στον καταχώρητη έχει αποθηκευτεί το παρακάτω σύνολο οδηγίων:

Φορτωσε τη θέση μνήμης 123 (η οποια περιλαμβάνει τον αριθμό 0101)
Φορτωσε τη θέση μνήμης 456 (η οποια περιλαμβάνει τον αριθμό 0011)
Πρόσθεσε τα δύο
Αποθηκευσε το αποτέλεσμα στη θέση μνήμης 789

Όπως βλέπουμε στα δύο πρώτα βήματα λειτουργεί μόνο η οδηγία φόρτωσης, στο τρίτο της πρόσθεσης και στο τεταρτο της αποθήκευσης. Αυτό έδωσε την ιδέα να χρησιμοποιηθεί στο μέγιστο η ικανοτητα του επεξεργστή με το να εκτελει και τις τεσσερις οδηγίες ταυτοχρονα. Δηλαδή ας υποθέσουμε ότι ενα δευτερο συνολο οδηγιων ειναι το εξης:

Αποθηκευσε τον αριθμό 0011 στη θέση μνήμης 345
Τιποτε
Τιποτε
Τιποτε

Τότε δεν είναι απαραίτητο να περιμένει ο επεξεργαστής να τελείωσει το πρώτο σύνολο οδηγιών για να εκτελεσθεί το δεύτερο, αλλά μπορεί να εκτελεσθεί ταυτοχρονα με το πρώτο, αφού οδηγια 1 είναι διαφορετική στις δύο περιπτώσεις. Από τη στιγμή που έχουμε ένα σύνολο οδηγιών που επαναλαμβάνεται πολλές φορες δημιουργήθηκε η ιδέα της διαδικασίας (procedure), που περιλαμβάνει ακριβώς ένα τέτοιο σύνολο οδηγιών. Μια διαδικασία μπορεί να καλεσθεί από ένα μεγαλύτερο σύνολο οδηγιων και να εκτελεσθεί στα πλαίσια αυτού του συνόλου. Επειτα μπορεί να χρησιμοποιηθεί από ένα άλλο σύνολο οδηγιων.

Αλλά τι είναι ένας υπολογιστής;

Στόχος αυτού του θέματος είναι να εξηγήσει τι είναι στα αλήθεια ένας υπολογιστής. Από τι αποτελείται και πως πραγματικά λειτουργεί. Για να τα καταλάβει κανείς αυτά δε χρειάζονται γνώσεις μαθηματικών, προγραμματισμού ή ηλεκτρονικής. Απλώς λογικής. Γι'αυτό και θα ξεκινήσουμε με τους πιο απλούς κανόνες λογικής, οι οποίοι ισχύουν από την εποχή του Αριστοτέλη.

Η βασική αρχή της Αριστοτελικής λογικής είναι ότι μία πρόταση μπορεί να είναι αληθης ή ψευδής. Δε μπορεί να είναι και αληθής και ψευδής ταυτόχρονα, αλλά ούτε και να είναι τίποτε άλλο εκτός απο αληθης ή ψευδής. Φυσικά υπάρχουν και άλλες λογικες όπως η τρίτιμη λογική του Lukasiewiz, ή η ασαφής λογική (fuzzy) αλλα οι υπολογιστές δε λειτουργούν ακόμη με αυτές. Ίσως στο μέλλον. Aς υποθέσουμε τώρα ότι έχουμε δύο προτάσεις π1 και π2. Η κάθε πρόταση μπορεί να είναι αληθής ή ψευδής, αρα οι δυνατοί συνδυασμοί είναι 4.
π1 αληθής, π2 αληθής
π1 αληθής, π2 ψευδής
π1 ψευδής, π2 αληθής
π1 ψευδής, π2 ψευδής

Η ερώτηση που τίθεται τώρα είναι τι συμβαίνει με την πρόταση "π1 και π2". Το αποτέλεσμα μπορεί να βρεθεί με το λεγόμενο πίνακα αλήθειας.
(Πρέπει να βάλω τον πίνακα εδώ)

Αλλά ας δούμε ένα παράδειγμα. π1="Σήμερα βρέχει" και π2="Χθες είχε ήλιο". Ας υποθεσουμε ότι όντως σημερα βρέχει και ότι όντως χθες είχε ήλιο. Τότε η π1 αληθεύει και η π2 αληθεύει. Τότε η π3= π1 και π2 ="Σήμερα βρέχει αλλά χθες είχε ήλιο" επίσης αληθεύει. Αν όμως χθες δεν είχε ήλιο, αρα η π2 είναι ψευδης, τότε και η π3="Σήμερα βρέχει αλλά χθες είχε ήλιο" είναι επίσης ψευδής.

Παρόμοιο πίνακα αλήθειας μπορούμε να συντάξουμε για το διαζευτικό ή (όχι αποκλειστικό).
(Πρέπει να βάλω τον πίνακα εδώ)

π1="Σήμερα θα βρέψει", π2="Σήμερα θα έχει ήλιο", π3=π1 ή π2="Σήμερα θα βρέξει ή θα έχει ήλιο" αληθεύει σε τρεις από τις τέσσερις περιπτώσεις, εκτός απο την περίπτωση δηλαδή που ούτε βρέξει ούτε έχει ήλιο (ίσως όταν έχει μόνο σύννεφα).

Υπάρχει βέβαια και το αποκλειστικό ή.
(Πρέπει να βάλω τον πίνακα εδώ)

Όπου πρέπει να αληθεύει το πολύ μία απο τις προτάσεις, όχι και οι δύο ταυτόχρονα, για να είναι και ο συνδυασμός τους αληθής.

Φυσικά όλα τα παραπάνω μπορούν να γραφούν με μαθηματικά ή ηλεκτρονικά σύμβολα και να διατυπωθούν σχέσεις μεταξύ τους. Ας υποθέσουμε προς στιγμή ότι οι παραπάνω πίνακες μπορούν να πραγματοποιηθούν ως πύλες (ηλεκτρονικα εξαρτηματα, θα αναφερθώ στη φυσική τους λειτουργία παρακάτω). Οι τιμές αληθής-ψευδής μπορούν να μεταφραστούν ως 0-1 ή υψηλή-χαμηλή τάση, όπως χρησιμοποιείται στην ηλεκτρονική. Έχουμε δηλαδή μια συσκευή που έχει δύο εισόδους (καλώδια, σωλήνες), τις π1 και π2, και μία έξοδο (καλώδιο, σωλήνας), την π3.
Αναλογα με το ποια συσκευη θα χρησιμοποιήσουμε μπορούμε να πραγματοποιήσουμε την αντίστοιχη πράξη. Οι είσοδοι αυτές δεν είναι τίποτε άλλο απο καλώδια με ρεύμα. Αν εχουν υψηλη ταση, αληθευουν. Με χαμηλή τάση ψεύδονται.

Οι παραπάνω πύλες μπορούν να συνδυαστούν είτε σε σειρά ή παράλληλα και να δώσουν άλλες πιο πολύπλοκες πύλες με περισσότερες εισόδους και εξόδους. Το αποτελεσμα μιας πύλης μπορεί να διοχευτεί σε ένα λαμπτήρα (παλιότερα χρησιμοποιούσαν λαμπτηρες πυρακτώσεως στους πρώτους υπολογιστές). Αν είναι υψηλή η τάση (1, αληθης) τότε θα ανάψει η λαμπα, αν είναι χαμηλή η τάση (0, ψευδής) δε θα αναψει η λάμπα. Ετσι έχουμε μια πρωτόγονη επικοινωνία με το χρήστη. Κατ'αναλογία μπορεί να φανταστεί κανείς τα pixel της οθόνης.

Μεχρι στιγμής είδαμε ότι μπορούμε να αναπαραστήσουμε μόνο 0-1, ψευδές-αληθες, και τίποτε παραπάνω. Θα αποδείξουμε τώρα ότι αυτή την αναπαρασταση μπορούμε να τη χρησιμοποιήσουμε για οτιδήποτε. Ας πάρουμε τους φυσικούς αριθμούς 1, 2, 3, 4, ... Το 1 είναι εύκολο. Το 2 γράφεται 1*2, το 3=1*2+1, 4=1*2*2, 5=1*2*2+1, 6=1*2*2+1*2, 7=1*2*2+1*2+1 κτλ. Όπως φαίνεται όλοι οι αριθμοί μπορούν να γραφούν ως γινομενο και άθροισμα του 1 και του 2. Ας θεωρήσουμε τώρα ότι έχουμε 8 λάμπες. Σβηστή είπαμε είναι 0, ανοιχτή 1. Τις βάζουμε σε σειρά. Το ένα αναπαρισταται απο αυτές τις λάμπες ώς εξης: οι 7 αριστερά ειναι σβηστες και η ογδοη ειναι ανοιχτη (00000001). Το δύο: οι 6 αριστερά ειναι σβηστες και η εβδομη ειναι ανοιχτη και η ογδοη σβηστη (00000010). Το τρία: οι 6 αριστερά ειναι σβηστες και η εβδομη ειναι ανοιχτη (00000011)και η ογδοη ανοιχτή. Το τέσσερα (00000100). Το πέντε (00000101). Και πάει λέγοντας.

Γιατί όμως ξεκινάμε από δεξία; Οι άραβες θα ξεκινούσαν από αριστερα; Το ίδιο ακριβώς πρόβλημα υπάρχει και στην αρχιτεκτονική επεξεργαστών. Ο τρόπος που παρουσιάσαμε παραπάνω ακολουθεί το συνηθισμένο τρόπο γραφής αριθμών και καλείται big endian. Αντίθετα, ο τρόπος που γράφουμε την ημερομηνία (27.06.2008) από τα μικρότερα ψηφία στα μεγαλύτερα λέγεται little endian. Aρχιτεκτονική big endian έχουν οι επεξεργαστές powerpc, sparc, ενώ little endian οι intel, amd και άλλοι.

Αν θελήσουμε να αναπαραστήσουμε και αρνητικούς αριθμούς τότε χρειαζόμαστε και μία ακομη λαμπα (bit) για το πρόσημο. Αν η πρώτη πρώτη λαμπα απο αριστερα είναι αναμένη τότε έχουμε αρνητικό αριθμό. (Για αυτούς που ξέρουν C αυτό αντιστοιχεί σε integer, ενώ η προηγούμενη αναπαρασταση σε unsigned)

Επειδή όμως έχουμε πεπερασμένο αριθμό από λάμπες δε μπορουμε να αναπαραστήσουμε όλους τους αριθμούς. Γι'αυτό και υπαρχει σε όλες τις γλώσσες προγραμματισμού ένα εύρος απο -12345678 μέχρι 12345678 (για παραδειγμα) που μπορεί να αναπαρασταθεί. Η αναπαράσταση πραγματικών αριθμών γίνεται με τη χρήση επιπλέον λαμπτήρων (bits) που αποθηκεύουν τη θέση της υποδιαστολής και τον εκθέτη του 10, αλλά δε θα ήθελα να μπώ εδώ σε τέτοιες λεπτομέρειες.

Έπειτα έρχεται η ερώτηση ναι αλλά εγώ δε θέλω μόνο αριθμούς θέλω και γράμματα, μικρά και κεφαλαία. Η απάντηση ήρθε με το αλφάβητο ASCII. Κάθε σύμβολο που χρησιμοποιείται έχει την αναπαράστησή του στο δεκαεξαδικό σύστημα (αντι να έχουμε λάμπες ανοιχτες-σβηστες, δυαδικό σύστημα δηλαδή, εχουμε λάμπες σβηστες+15 χρώματα δεκαεξαδικό δηλαδή). Ετσι μπορούμε να χρησιμοποιούμε λατινικούς χαρακτήρες, μικρά κεφαλαια, και άλλα σύμβολα. Μετά φυσικά ήρθαν και άλλες κωδικοποιήσεις για τις οποίες δεν έχω ιδέα

Εισαγωγή σε parallel computing

Όλο και πιο συχνά ακούγεται στις μέρες μας ο όρος parallel computing, παράλληλοι υπολογισμοί, και έχει γίνει πλέον και στους προσωπικούς υπολογιστές πραγματικότητα με επεξεργαστές διπλών και τρίδιπλων (όπως το λαϊκό) επεξεργαστών. Αλλά ποιος ο λόγος και υπάρχει πράγματι κέρδος από τους επεξεργαστές με δύο πυρήνες ή είναι απλώς ένα εμπορικό παιχνίδι των εταιριών για να αυξήσουν τα κέρδη τους; Αυτή την ερώτηση δυστυχώς αδυνατώ να απαντήσω αλλά θα σας δώσω μια απλή γεύση του πως μπορούμε να εκμεταλλευτούμε αυτή τη δυνατότητα.

Oι παράλληλοι υπολογιστές χωρίζονται σε δύο βασικές κατηγορίες (επιτρέψτε μου την αγγλική ορολογία): shared και distributed μνήμης υπολογιστές. Οι πρώτοι, shared memory, είναι αυτοί που έχουμε στους υπολογιστές μας, όπου ο κάθε επεξεργαστής (στο σημείο αυτό δε θα τους ξεχωρήσω από τους πυρήνες) μοιράζεται την ίδια μνήμη με όλους τους υπόλοιπους. Οι distributed memory υπολογιστές έχουν ο καθένας δική του μνήμη και επικοινωνούν μέσω δικτύου. Προφανώς αν έχουμε 100 επεξεργαστές είναι λίγο δύσκολο να τους καλωδιώσουμε ώστε να μοιράζονται την ίδια μνήμη, ίσως στο μέλλον. Η δημιουργια, ο προγραμματισμός και η χρήση distributed memory είναι αρκετά προχωρημένη και δε θα ασχοληθω εδώ καθόλου.

Ας συνεχίσουμε λοιπόν με shared memory υπολογιστές. Για τα παρακάτω θα χρειαστούν:

sudo apt-get install build-essential libgomp

build-essential περιέχει όλα τα απαραίτητα πακέτα για προγραμματισμό και αναπτυξη κώδικα
libgomp περιέχει τη βιβλιοθήκη για shared memory parallel programming

Aναλυτικές οδηγίες για την gnu openMP μπορούν να βρεθούν http://gcc.gnu.org/onlinedocs/libgomp/

Θα ξεκινήσω με ένα απλό hello world πρόγραμμα σε C. Δημιοργούμε καταρχήν ένα φάκελο

mkdir ~/testgomp
cd ~/testgomp

Ανοίγουμε μέσα στο φάκελο testgomp με το gedit το αρχείο hello.c

gedit hello.c &


Kαι εισάγουμε τα παρακάτω:

int main()
{
printf("Hello world\n");
}

To μεταγλωττίζουμε και δημιουργούμε το εκτελέσιμο με:

gcc -c hello.c
gcc -o serialtest hello.o

Eκτελούμε το πρόγραμμα που δημιουργήθηκε με

./serialtest


και βλέπουμε ότι εκτυπώνεται στην οθόνη Hello world μόνο μία φορά.

Tώρα προσθέτουμε τη γραμμή #pragma omp parallel δηλαδή το αρχείο θα πρέπει να φαίνεται:

int main()
{
#pragma omp parallel
printf("Hello world\n");
}

To μεταγλωττίζουμε (τώρα χρειάζεται να συνδέσουμε επίσης την αντίστοιχη βιβλιοθήκη) και δημιουργούμε το εκτελέσιμο με:

gcc -c -fopenmp hello.c
gcc -o paralleltest hello.o

Εκτελούμε τώρα το παράλληλο πρόγραμμα με

./paralleltest


και βλέπουμε να τυπώνεται δύο φορές ενώ υπάρχει μόνο μία φορά στον κώδικά μας και δεν υπάρχει φυσικά κανένας βρόγχος. (Φυσικά αν έχουμε επεξεργαστή με ένα μόνο πυρήνα δε θα δούμε διαφορά)
Η γραμμή #pragma omp parallel αντιλαμβάνεται από το μεταγλωττιστή gcc σαν σχόλιο αν δεν υπάρχει η επιλογή -fopenmp κατά τη μεταγλώττιση, πράμα που επιτρέπει ένα πρόγραμμα που γράφουμε να είναι αρκετά portable.

Φυσικά αυτό δεν είναι και πολύ χρήσιμο γιατί επαναλαμβάνει την ίδια δουλειά δύο φορές. Εμείς χρειαζόμαστε κάτι που να μοιράζει το φόρτιο εργασίας στους δύο επεξεργαστές.
Aς δημιουργήσουμε τώρα ένα άλλο αρχείο hello2.c που θα περιέχει τα εξης:

#define N 100000
int main()
{
int i, a[N];
#pragma omp parallel for
for (i=0;i< style="font-weight: bold;"> a[i]= 2*i;
return 0;
}

Και μεταγλώττιση όπως πάντα με

gcc -c -fopenmp hello2.c
gcc -o paralleltest2 hello2.o

Το συγκεκριμένο παράδειγμα μοιράζει αυτόματα το array a[N] στα δύο threads που δημιουργούνται. Τα αποτελέσματα είναι σωστά γιατί το δεξί μέλος της ισότητας δεν εξαρτώνται από το αριστερό.

Aν είχαμε όμως κάτι όπως αυτό:


#define N 100000

int main()
{
int i, a[N];
a[0]=0;
#pragma omp parallel for
for (i=1; i<> a[i]= a[i-1]+1;
return 0;
}

δε θα λειτουργούσε γιατι κάθε επόμενο στοιχείο του a θα εξαρτάται από το προηγούμενο, αρα για να υπολογισει το στοιχειο 50000 στο δεύτερο thread θα χρειάζεται το 49999 από το πρώτο thread το οποίο δεν έχει υπολογιστεί ακομη.

Σε distributed memory υπολογιστές όπου τα δεδομένα, το a στο παράδειγμά μας, δεν είναι σε κοινή μνήμη θα πρέπει να μεταφέρονται από επεξεργαστή σε επεξεργαστή (για περισσότερες πληροφοριές δες http://en.wikipedia.org/wiki/Message_Passing_Interface) Yπάρχουν διάφορα εργαλεία για να στηθεί ένα [/url=http://en.wikipedia.org/wiki/Computer_cluster]cluster[/url] (distributed memory υπολογιστής) φυσικά και σε linux.

Βιβλιογραφία
1. http://openmp.org/wp/
2. http://gcc.gnu.org/onlinedocs/libgomp/
3. http://en.wikipedia.org/wiki/OpenMP
4. http://en.wikipedia.org/wiki/Parallel_computing