PDA

View Full Version : High performance computing.


DarthMoul
12-07-2004, 07:09
Ασχολείται κανείς με το αντικείμενο; Όσοι γράφουν κώδικα, ανεξάρτητα γλώσσας και λειτουργικού έχουν να ωφελειθούν πολλά. Και θα δώσουν και παραπάνω ζωή στα μηχανήματα που θα τρέξουν τις εφαρμογές τους. Παράλληλα μαθαίνεις "από μέσα" πως δουλεύει η μηχανή και έχει και πλάκα.

Alarm
12-07-2004, 13:23
sorry αλλα δεν καταλαβα... περι τεινος προκειται ?

soler
12-07-2004, 17:07
Βασικα ουτε εγω καταλαβα....

Linos80
12-07-2004, 17:19
Φιλε DarthMoul αν μιλας για code optimization κανε την αρχη να δουμε αν θα υπαρξει ανταποκριση.Θα χαρουμε πολυ να εχουμε σπουδαια και σημαντικα post τετοιου τυπου απο σενα!!! :059:

DarthMoul
12-07-2004, 19:24
Λοιπόν. Να τα πάρουμε με την σειρά και με απλά λόγια. Για να καταλάβουμε τί είναι το High Performance Computing (HPC για συντομία) πρέπει να πούμε πρώτα το είναι το computing, σωστά;
Computing είναι ή χρήση software και hardware για την επίλυση ενός προβλήματος. Είναι αυτό που κάνουμε όλοι μας εδώ. Δεν παίζει ρόλο αν κανείς παίζει παιχνίδια, γράφει στο word, κάνει folding ή τηρεί τα λογιστικά του βιβλία με χρήση υπολογιστή. Όλες αυτές οι διαδικασίες ονομάζονται computing. H χρήση υπολογιστή γενικότερα ονομάζεται computing.

Τώρα τι είναι το HPC; Υπάρχουν προβλήματα, των οποίων η προσπάθεια επίλυσης προκαλεί ιδιαίτερα υψηλό υπολογιστικό φορτίο. Τέτοια προβλήματα είναι πρόβλεψη που παγκοσμίου κλίματος, η αποκωδικοποίηση του ανθρωπίνου γονιδιόματος, η πρωτεϊνική ανάλυση, η εξομοίωση της πυρινικής σχάσης κλπ. Έτσι λοιπόν, έχουμε ανάγκη για υπολογιστική ισχή πολύ μεγαλύτερη απ'ότι απαιτούν τα συνήθη προβλήματα που επιλύουμε σε καθημερινή βάση. Αρχικά για την επιλυση τους χρησιμοποιούσαμε τεράστιους υπερυπολογιστές και όλη διαδικασία ονομαζόταν supercomputing. Με την πάροδο του χρόνου όμως και την πρόοδο των ηλεκτρονικών το supercomputing κατέστει οικονομικά ασύμφορο και ως πιο δόκιμη λύση εφαρμόστηκε η κλιμάκωση commodity hardware, δηλαδή του ίδιου hardware που χρησιμοποιούμε και εμείς στα σπίτια μας ή σχεδόν του ίδιου. Έτσι λοιπόν γεννηθηκαν οι superclusters που χρησιμοποιούνται σήμερα ευρέως για την λύση προβλημάτων με πολύ υψηλές υπολογιστικές απαιτήσεις. Αν συνδιάσετε τους superclusters με προγραμματιστικές μεθόδους που έχουν σκοπό την όσο το δυνατόν μεγαλύτερη αξιοποίηση τους, τότε έχετε το HPC. Το code optimization που μας είπε παραπάνω ο Linos είναι η σημαντικότερη παράμετρος από πλευράς software για την αξιοποίηση τέτοιων συστημάτων. Όλες οι μέθοδοι βελτιστοποίησης κώδικα πρώτα ανακαλύπτονται και δοκιμάζονται σε τέτοια συστήματα γιατί εκεί υπάρχει η επιτακτική ανάγκη για κάτι τέτοιο. Από πλευράς hardware o πιο σημαντικός παράγοντας είναι η δυκτίωση.

Παλιότερα οι αναφορές ήταν στο High Performance Technical Computing (HPTC) αλλά τα τελευταία χρόνια ο όρος technical αποφεύγεται γιατί υπάρχουν και προβλήματα μη τεχνικής φύσεως που έχουν ανάγκη από high performance clusters για την επίλυση τους.
Τώρα θα μου πείτε, και τι μας νοιάζει εμάς εδώ όλη αυτή η ιστορία. Καταρχήν οι superclusters είναι η Formula 1 των υπολογιστών και μπορείτε να τους δείτε εδώ: http://www.top500.org Αφού έχουμε το ψώνιο, μας νοιάζει!!!
Και φυσικά αφού χρησιμοποιούν το ίδιο hardware που έχουμε και εμείς στα σπίτια μας ή στις δουλειές μας, μπορούμε να χρησιμοποιήσουμε πολλές από τις μεθόδους βελτιστοποίησης που χρησιμοποιούν εκεί κάνοντας τις εφαρμογές μας να πετάνε. Αυτό προϋποθέτει πως το πρόγραμμα το έχουμε γράψει εμείς ή ότι έχουμε τα sources. Σε αντίθετη περίπτωση, η άλλη επιλογή που έχουμε είναι το overclocking. Το code optimization βέβαια έχει το πλεονέκτημα ότι δεν βάζει σε κανέναν κίνδυνο το σύστημα μας και δεν προκαλεί κόστος. Και την προϋπόθεση ότι γνωρίζουμε καλά τουλάχιστον μία γλώσσα προγραμματισμού. Τέλος, αν μπούμε στην διαδικασία αναγκαζόμαστε να κατανοήσουμε πως λειτουργεί η μηχανή "από μέσα" και ανακαλύπτουμε τεχνικές λεπτομέριες και διαφορές μεταξύ αρχιτεκτονικών που σε άλλη περίπτωση θα μας διέφευγαν. Αυτό θα μας βοηθήσει σε μελλοντικές επιλογές hardware ανάλογα με τις ανάγκες μας. Και φυσικά έχει και πλάκα, ειδικά όταν ανακαλύπτουμε την ποιότητα και τις αδυναμίες του software που κάποιες εταιρίες μας πουλάνε πανάκριβα :110:

MrSeanKon
13-07-2004, 00:26
Βασικα θα συνιστουσα στο φιλο μας να ειναι οσο γινεται πιο ευκολοχωνευτος διοτι τετοιες εννοιες θελουν αναπτυξη με προσοχη.
Απο αυτα που αναφερει δεν εχω σχετικη επαφη τωρα προσπαθω να μαθω OOP για να Windowsποιησω :D:D:D τα O/c Tools (σιχαμενο MS DOS)....... :046:

Linos80
13-07-2004, 01:34
Ο φιλος Darthmoul εχει απολυτο δικιο.
Πραγματικα με το overclocking 8α κερδισεις ισως ενα μικρο ποσοστο % στην αποδοση ενω με την βελτιστοποιηση ενος κωδικα και την δημιουργια ενος πιο <<εξυπνου>> αλγοριθμου μπορεις να κερδισεις 10πλασιες φορες σε χρονο εκτελεσης.
Το γεγονος αυτο βεβαια δεν περιοριζει κανενας μας να βρισκουμε τα ορια των μηχανηματων μας σε επιπεδο hardware αλλα φυσικα θα ηταν ευχης εργο να ειχαμε στην ομαδα μας ανθρωπους που ασχολουνται με optimization σε επιπεδο software ωστε να κανουμε κι εκει τις αναλυσεις μας και να βγαλουμε τα συμπερασματα μας!!! :038:

Alarm
13-07-2004, 02:01
κανω ενα μαθημα το οποιο λεγεται "Data Structure & Algorithms" αλλα δεν πιστευω πως ειμαι σε θεση να παρεσχω μεγαλη βοηθεια καθως το επιπεδο ειναι ακομη χαμηλο για να μιλησουμε για HPC

DarthMoul
13-07-2004, 07:56
Μια και υπάρχει ενδιαφέρον θα συνεχίσω. Κατ'αρχήν η μόνη προϋπόθεση για να καταλάβει κάνείς αυτά που θα πούμε εδώ είναι η γνώση μιας γλώσσας προγραμματισμού. Η καλύτερη για αυτές τις δουλειές είναι η C αλλά όσα θα πούμε στην συνέχεια εφαρμόζονται σχεδόν σε κάθε γλώσσα. Όντως με το code optimization κεδρίζεις πολύ περισσότερο απ'ότι με το overclocking. Αν το 50% με το overclocking είναι κάτι δύσκολο, εδώ μιλάμε για το 1/3 ή το 1/5 ή και το 1/25 του αρχικού χρόνου εκτέλεσης. Επίσης ο καλογραμμένος κώδικας έχει απ'την φύση του καλύτερο frequency scaling, άρα το overclocking ή η αναβάθμιση θα αποδώσουν πολύ καλύτερα.

Η διαδικασία είναι πολλές φορές επίπονη και κάνει τον κώδικα να φαίνεται "άσχημος" και δύσκολα συντηρίσιμο. Γι αυτόν τον λόγο χρειάζεται προσοχή και εξυπνάδα. Για κέρδη μικρότερα του 20% δεν μπαίνουμε καν στον κόπο αν δεν υπάρχει πραγματική ανάγκη. Παρακάτω θα πούμε ένα - ένα τα βήματα που ακολουθούμε και θα κάνουμε και ένα παράδειγμα. Δυστυχώς το ζήτημα είναι τεράστιο και μέσα σε ένα φόρουμ δεν μπορούμε να το καλύψουμε σε μεγάλη έκταση, αλλά νομίζω θα είναι καλή αρχή για όσους θέλουν να ασχοληθούν.

DarthMoul
13-07-2004, 08:42
Εδώ λοιπόν έχουμε τα βήματα που πρέπει να ακολουθήσει κανείς αν θέλει να κάνει τις εφαρμογές του πετάνε.
1. Πρώτα απ’ όλα επιλέγουμε ή σχεδιάζουμε τον κατάλληλο αλγόριθμο που θα μας λύσει το πρόβλημα. Κανένα optιmization δεν θα κάνει την εφαρμογή μας πραγματικά γρήγορη αν δεν έχουμε διαλέξει τον σωστό αλγόριθμο. Αλγόριθμος πανάκεια δεν υπάρχει. Αν χρησιμοποιήσουμε πχ δέντρα ενώ το πρόβλημα χρειάζεται λίστες ό,τι και να κάνουμε θα βγούμε χαμένοι.
2. Γράφουμε την ρουτίνα μας αδιαφορώντας παντελώς για τις επιδόσεις της. Αυτό που μας ενδιαφέρει σε αυτήν την φάση είναι να παράγει το σωστό αποτέλεσμα. Τα υπόλοιπα είναι δευτερεύοντα.
3. Φτιάχνουμε ένα πλήρες test suite. Τι είναι αυτό; Είναι μια σειρά από προγράμματα που ελέγχουν κατά πόσο η ρουτίνα παράγει το σωστό αποτέλεσμα και τα αναμενόμενα μηνύματα λάθους.
4. Έχουμε κοντά μας έναν debuger γιατί μάλλον θα χρειαστεί. Ειδικά σε μεγάλα projects θα χρειαστεί σίγουρα.
5. Έχουμε κοντά μας έναν profiler γιατί μπορεί και αυτός να χρειαστεί. Τι είναι ο profiler; Είναι ένα πρόγραμμα που παράγει στατιστικά για τον χρόνο εκτέλεσης του προγράμματος, πόσο χρόνο αναλώνει και πόσες φορές καλεί κάθε υπορουτίνα ή ακόμα και γραμμή του κώδικα μας, Οι πιο εξελιγμένοι όπως ο Vtune της Intel δίνει ακόμα και hints. Όλη αυτή η διαδικασία ονομάζεται καταχρηστικά profiling γι αυτό και το πρόγραμμα που αναλαμβάνει την δουλειά το βαφτίσανε profiler. Το profiling είναι όρος που μας έρχεται από την τέχνη της ζωγραφικής. Ο σωστός όρος είναι instrumentation. Εμείς όμως θα λέμε profiling γιατί είμαστε καλλιτέχνες.
:p
Και αφού τα κάνουμε όλα αυτά θα πρέπει να καθορίσουμε τον τρόπο που θα μετράμε τις επιδόσεις μας έτσι ώστε να είναι αξιόπιστα και τα συμπεράσματα που θα βγάλουμε μετά τις επεμβάσεις που θα κάνουμε πάνω στον αρχικό κώδικα.

Κατ’ αρχήν, θα πρέπει να μετράμε το πρόγραμμα μας με το σύστημα κάτω από το σύνηθες φορτίο. Άλλωστε υπό αυτές τις συνθήκες θα τρέξει. Αν θέλουμε να είμαστε ιδιαίτερα ακριβείς, κάνουμε 9 μετρήσεις, πετάμε έξω την καλύτερη και την χειρότερη, και βγάζουμε τον μέσο όρο από τις υπόλοιπες 7. Αν δεν μας ενδιαφέρει ιδιαίτερα η ακρίβεια, κάνουμε τρεις μετρήσεις και χρησιμοποιούμε για γνώμονα την ενδιάμεση.

DarthMoul
13-07-2004, 10:40
Έχουμε λοιπόν το παρακάτω σενάριο. Σε μία αντιπροσωπία αυτοκινήτων η αποθήκη έχει 300,000 διαφορετικά ανταλλακτικά. Όλα αυτά είναι καταχωρημένα σε μια βάση δεδομένων που την προσπελαύνουν 20 χρήστες. Η αναζήτηση γίνετε πάντα με το part number που περιλαμβάνει αριθμούς και κεφαλαίους αγγλικούς χαρακτήρες. Τι θα γίνει αν κάποια στιγμή κάποιος κατά λάθος πατήσει μικρούς αγγλικούς; Χρειαζόμαστε λοιπόν μία ρουτίνα που να ελέγχει τι πληκτρολόγησε ο χρήστης και να κάνει τις ανάλογες μετατροπές. Η στατιστική λέει ότι κάθε χρήστης κάνει κατά μέσο όρο 6 αναζητήσεις την ώρα.

DarthMoul
13-07-2004, 10:50
Eδώ είναι λοιπόν η ρουτίνα που φτιάξαμε σε C

/* convert.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void convert(char *string, char *invalid, char *valid)
{
int i, j;

/* Το valid και το invalid θα πρέπει να είναι του ιδίου μεγέθους.
Εδώ κάνουμε τον έλεγχο */

if (strlen(invalid) != strlen(valid))
{
printf("\nconvert: Arguments 2 and 3 are not of the same size. Exiting");
exit(1);
}

/* Και εδώ ελέγχουμε και μετατρέπουμε αναλόγως.
Για κάθε χαρακτήρα του string ελέγχουμε αν υπάρχει αντίστοιχος
χαρακτήρας στο invalid. Σε αυτήν την περίπτωση τον αντικαθιστούμε
με τον αντίστοιχο χαρακτήρα του valid.
*/
for(i=0; i<strlen(invalid); i++)
for(j=0; j<strlen(string); j++)
if (invalid[i] == string[j])
string[j] = valid[i];
}

DarthMoul
13-07-2004, 10:54
Με αυτό το προγραμματάκι ελέγχουμε αν δουλεύει σωστά αυτό που φτιάξαμε:

/* cnvtest.c */

#include "convert.c"
#include <stdio.h>
main()
{
char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
invalid[] = "abcdefghijklmnopqrstuvwxyz",
teststring[] = "we are converting from a to z";
convert(teststring, invalid, valid);
printf("\n %s \n", teststring);
}

DarthMoul
13-07-2004, 11:13
Και με αυτό μετράμε τις επιδόσεις του:

/* cnvbench.c */

#include "convert.c"
#include <stdio.h>
main()
{
int i;
char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
invalid[] = "abcdefghijklmnopqrstuvwxyz",
teststring[] = "we are converting from a to z";
for(i=0; i < 300000; i++)
convert(teststring, invalid, valid);
}

και να η μέτρηση:

lucast70@alpha:~/optimize$ cc cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m31.254s
user 0m31.040s
sys 0m0.006s
lucast70@alpha:~/optimize$ time cnvbench

real 0m31.251s
user 0m31.039s
sys 0m0.007s
lucast70@alpha:~/optimize$ time cnvbench

real 0m31.249s
user 0m31.039s
sys 0m0.005s

DarthMoul
13-07-2004, 11:44
Για να το σκεφτούμε λιγάκι το ζήτημα. Για 300000 ελέγχους, δηλαδή όσα τα records της βάσης μας θέλουμε περίπου 30''. Επί 20 χρήστες και αυτό επί 6 φορές την ώρα πέρνουμε το μαγικό νούμερο 3600 δευτερόλεπτα. Δηλαδή όσα ακριβώς είναι τα δευτερόλεπτα μιας ώρας. Με άλλα λόγια, το σύστημα μας θα απασχολείται 100% μόνο με αυτή την διαδικασίας. Και φυσικά δεν είναι αυτή η μόνη δουλειά που έχει να κάνει ο server μας. Και όποιος πάει στο αφεντικό να του πει πως πρέπει να αγοράσουμε καινούργιο server μάλλον η απάντηση θα είναι αυτή :021:

Για να κάνουμε μια δοκιμή με τον optimizer του compiler να δούμε τι έχει να μας δώσει:

lucast70@alpha:~/optimize$ cc -O2 cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.146s
user 0m22.004s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.141s
user 0m22.006s
sys 0m0.002s
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.141s
user 0m22.004s
sys 0m0.003s

Σχεδόν 30% βελτίωση. Καλό αλλά λίγο. Και πάλι το σύστημα θα απασχολείται κατά 70% γι αυτήν την αστεία μεν αλλά αναγκαία διαδικασία

Alarm
13-07-2004, 12:29
καλη φαση αδελφε, αλλα...
ο κωδικας μπορει να ειναι μικρος μεν , αλλα μην ξεχνας πως δεν τον εχουμε γραψει εμεις. που συμενει πως μερικες σημειωσεις διπλα απο τον κωδικα δεν θα ηταν ασχημες.

ΥΓ. εχεις ενα μικρο λαθακι, ο κωδικας τρεχει μεν, αλλα η συναρτηση "main" επιστρεφει παντα "int"

αρα:

int main(void)
{
...code
return 0;
}

DarthMoul
13-07-2004, 13:18
καλη φαση αδελφε, αλλα...
ο κωδικας μπορει να ειναι μικρος μεν , αλλα μην ξεχνας πως δεν τον εχουμε γραψει εμεις. που συμενει πως μερικες σημειωσεις διπλα απο τον κωδικα δεν θα ηταν ασχημες.

ΥΓ. εχεις ενα μικρο λαθακι, ο κωδικας τρεχει μεν, αλλα η συναρτηση "main" επιστρεφει παντα "int"

αρα:

int main(void)
{
...code
return 0;
}
Πρόσθεσα ένα ακόμα σχόλιο στο convert.c
Σχετικά είναι ότι απλούστερο θα μπορούσε να κάνει κανείς. Χρησιμοποιώ το c89 ansi standard. Η παρατήρηση σου είναι σωστή για το iso c99 standard. Αν γράψω έτσι οι c89 compilers θα χτυπήσουν. Τέλος πάντων δεν είναι αυτό το θέμα. Θα μπορούσε να είναι pascal ή java ή visual basic.
Θα περιμένω 1-2 μέρες για παρατηρήσεις και απορίες πριν προχωρήσω παρακάτω ώστε να βάλουμε στον κώδικα όλα τα σχόλια που χρειάζεται για να τον καταλάβουν όλοι.

Linos80
13-07-2004, 14:33
Πριν συνεχισεις να σε ευχαριστησω γι'αυτο το ουσιαστικο και χρησιμοτατο thread το οποιο κοσμει την κατηγορια.Πλεον γινεται sticky γιατι θεωρουμε οτι ολοι, ανεξαρτητα απο το αν ασχολουνται με προγραμματισμο ή οχι, πρεπει να ξερουν οτι εκτος απο το <<hardware-ικο>> overclocking υπαρχει και η <<software-ικη>> πλευρα του που οταν χρησιμοποιηθει καταλληλα μπορει να αυξησει σε κατακορυφα επιπεδα την αποδοση του συστηματος μας σε καποια εφαρμογη-ρουτινα. :023:

Alarm
13-07-2004, 16:43
σωστος . πρεπει να γινει sticky . μαζι σου αδελφε

DarthMoul
16-07-2004, 07:48
Αν λοιπόν θέλουμε να κατεβάσουμε κι άλλο τους χρόνους της εφαρμογής μας, θα πρέπει να κάνουμε μια μικρή μελέτη πάνω στον κώδικα της, να συλλέξουμε στατιστικά, και να δούμε που τελικά πονάει. Κατ΄αρχήν θα πρέπει να ξέρουμε για τι πράγμα ψάχνουμε, και να ιεραρχήσουμε τις προτεραιότητες μας. Πάντα ψάχνουμε γι αυτό που κοστίζει πιο πολύ. Και τι κοστίζει περισσότερο;
1. Η προσπέλαση σε δίσκο, κάποιο περιφεριακό ή και υποσύστημα (πχ VGA)
2. Η κλήση συνάρτησης/υπορουτίνας
3 Οι έλεγχοι if, do/while και for
4. Τα memory movements
5. Οι υπολογισμοί
Με την σειρά που τα γράψαμε. Επίσης υπάρχουν και οι λεγόμενοι silent performance killers όπως τα misalignments, το data dependency και τα cache misses για τα οποία όμως θα μιλήσουμε πιο κάτω.
Για την μελέτη μας θα χρειαστούμε έναν profiler. Επειδή όπως είμαστε παιδιά με όρεξη και το πρόβλημα απλό, θα κάνουμε την μελέτη μας "με το χέρι", δηλαδή θα κάνουμε μόνοι μας ένα μέρος της δουλειάς που θα έκανε ο profiler.
Την επόμενη φορά όμως, θα διαβάσουμε προσεκτικά το manual του profiler που έχει το σύστημα μας και θα δουλέψουμε με αυτόν. Τα πραγματικά προβλήματα άλλωστε είναι πολύ πιο σύνθετα από το φανταστικό στο οποίο δουλεύουμε.

DarthMoul
16-07-2004, 19:15
Για να δούμε τι έχουμε. Ο πυρήνας της υπορουτίνας που δουλεύουμε είναι αυτός:

for(i=0; i<strlen(invalid); i++)
for(j=0; j<strlen(string); j++)
if (invalid[i] == string[j])
string[j] = valid[i];

Εδώ γίνεται ουσιαστικά όλη η δουλειά. Παρατηρούμε ότι έχει :
1. κλήσεις συνάρτησης: strlen(invalid) και strlen(string)
2. ελέγχους μέσα σε if και for: i<strlen(invalid), j<strlen(string) μέσα στα 2 for και άλλη μία if (invalid[i] == string[j])
3. memory movements: string[j] = valid[i];
4. και υπολογισμούς μέσα στα for: I++ και j++

Το πρώτο for θα εκτελεστεί 26 φορές, δηλαδή όσα τα γράμματα του αγγλικού αλφαβήτου και θα προκαλέσει 26 function calls, 26 conditions και 26 calculations.
Το δεύτερο θα εκτελείτε 29 φορές, δηλαδή όσο είναι το μήκος τους string:
"we are converting from a to z" το οποίο χρησιμοποιούμε για να κάνουμε τις δοκιμές μας. Αυτό το loop όμως είναι «φωλιασμένο» μέσα στο πρώτο. Άρα θα εκτελεστεί συνολικά 29 χ 26 = 754 φορές και θα προκαλέσει με την σειρά του
754 function calls, 754 conditions και 754 calculations.
Επίσης 754 φορές θα εκτελεστεί και ο έλεγχος if (invalid[i] == string[j]), άρα
Έχουμε άλλα 754 conditions.
Τέλος το memory movement string[j] = valid[i] θα εκτελεστεί όσες φορές το if είναι αληθές και δεν θα ασχοληθούμε μαζί του γιατί είναι αναπόφευκτο. Όπως και να έχει το ζήτημα θα κάνουμε τόσα memory movements όσους invalid χαρακτήρες έχουμε στο string.
Πάμε να αθροίσουμε:
1. function calls: 26 συν 754 συν τα 2 στην αρχή για τον έλεγχο εγκυρότητας έχουμε σύνολο: 782
2. Έλεγχοι (conditions): 26 συν 754 συν 754 συν 1 αρχή για τον έλεγχο εγκυρότητας έχουμε σύνολο: 1535
3. Υπολογισμοί: 754 συν 26 σύνολο: 780


Τώρα που πλέον ξέρουμε τι μας γίνεται έχουμε δύο επιλογές. Η μία είναι να προσπαθήσουμε να βελτιώσουμε τον υπάρχοντα αλγόριθμο, και η άλλη να προσπαθήσουμε να σχεδιάσουμε έναν καινούργιο που να έχει καλύτερη συμπεριφορά δηλαδή λιγότερες συνθήκες και λιγότερα function calls ή τουλάχιστον να επιδέχεται περισσότερες βελτιώσεις.

Θα τα δοκιμάσουμε και τα δύο και θα διαλέξουμε στο τέλος το καλύτερο.

DarthMoul
16-07-2004, 20:32
Ο #1 εχθρός μας λοιπόν που είναι τα function calls εμφανίζεται 782 φορές. Παρατηρούμε ότι υπάρχουν function calls μέσα σε loops. Αυτό που μπορούμε να κάνουμε εδώ είναι να καλέσουμε τα functions πριν μπούμε στα loops και να αποθηκεύσουμε την επιστροφή τους μέσα σε μεταβλητές. Μετά, μπαίνοντας στα loops, αντί να καλούμε functions θα χρησιμοποιούμε τις μεταβλητές. Έτσι μπορούμε να μειώσουμε τα function calls από 782 σε 3. Για να δούμε πως θα γίνει ο κώδικας μας:

/* convert.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void convert(char *string, char *invalid, char *valid)
{
int i, j, ilen, vlen, slen;

ilen = strlen(invalid);
vlen = strlen(valid);
slen = strlen(string);

/* Το valid και το invalid θα πρέπει να είναι του ιδίου μεγέθους.
Εδώ κάνουμε τον έλεγχο */

if (ilen != vlen)
{
printf("\nconvert: Arguments 2 and 3 are not of the same size. Exiting");
exit(1);
}

/* Και εδώ ελέγχουμε και μετατρέπουμε αναλόγως.
Για κάθε χαρακτήρα του string ελέγχουμε αν υπάρχει αντίστοιχος
χαρακτήρας στο invalid. Σε αυτήν την περίπτωση τον αντικαθιστούμε
με τον αντίστοιχο χαρακτήρα του valid.
*/

for(i=0; i<ilen; i++)
for(j=0; j<slen; j++)
if (invalid[i] == string[j])
string[j] = valid[i];
}

DarthMoul
16-07-2004, 20:36
Και τώρα πάμε να μετρήσουμε το αποτέλεσμα της επέμβασης μας:

lucast70@alpha:~/optimize$ cc cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m10.379s
user 0m10.354s
sys 0m0.003s
lucast70@alpha:~/optimize$ time cnvbench

real 0m10.378s
user 0m10.355s
sys 0m0.002s
lucast70@alpha:~/optimize$ time cnvbench

real 0m10.378s
user 0m10.356s
sys 0m0.001s

Για να φωνάξουμε και τον optimizer του compiler να δούμε τι παραπάνω μπορεί να κάνει:
lucast70@alpha:~/optimize$ cc -O2 cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.278s
user 0m3.269s
sys 0m0.003s
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.277s
user 0m3.268s
sys 0m0.003s
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.276s
user 0m3.267s
sys 0m0.001s

DarthMoul
17-07-2004, 12:15
Μειώνοντας τα function calls από 782 σε μόνο τρία βλέπουμε ότι:
Χωρίς την χρήση του optimizer ο χρόνος εκτέλεσης έπεσε από 31.251s σε 10.378s δηλαδή στο 33.2% του αρχικού χρόνου. Με την χρήση του optimizer έχουμε πτώση από 22.141s σε μόλις 3.277 δηλαδή στο 14.8% του αρχικού χρόνου. Αυτό δείχνει πόσο πολύ επιβαρύνουν τα άσκοπα function calls μια εφαρμογή. Και φυσικά υπάρχει κάποια αιτία γι αυτό.

Κάθε φορά που ο compiler συναντά ένα function call σε γενικές γραμμές λειτουργεί ως εξής: Κατ’ αρχήν κάνει push όλους τους registers στο stack. Κατόπιν κάνει ένα long jump στην διεύθυνση που βρίσκεται ο κώδικας της συνάρτησης που καλούμε. Αν η συνάρτηση δέχεται λίγες παραμέτρους θα τις περάσει μέσα σε registers. Αν έχει πολλές θα κάνει αναφορά στην μνήμη και αυτό προκαλέσει ακόμα μεγαλύτερη επιβάρυνση. Αφού τελειώσει η εκτέλεση της συνάρτησης θα κάνει pop όλους τους registers και θα συνεχίσει από την επόμενη εντολή μετά το long jump.

Παράλληλα με τις διαρκείς κλήσεις επιβαρύνουμε και την L1 cache. Η L1 cache χωρίζεται σε δύο κομμάτια. Η Icache (instruction cache) όπου εκεί βρίσκονται οι εντολές εκτελέστηκαν πρόσφατα, και η Dcache (data cache) όπου εκεί βρίσκονται οι μεταβλητές που προσπελάσαμε πρόσφατα. Το ζήτημα είναι ότι με τα multitasking λειτουργικά, είναι μάλλον απίθανο το πρόγραμμά μας να μονοπωλεί την μηχανή. Το αποτέλεσμα είναι όλες οι άλλες διεργασίες που εκτελούνται παράλληλα να βρίσκουν το Icache «βρώμικο» λόγω των συνεχών δικών μας άσκοπων κλήσεων, και αργότερα όταν ο έλεγχος περνάει στο δικό μας πρόγραμμα βρίσκουμε το Icache «βρώμικο» εμείς. Έτσι λοιπόν πέφτουμε σε έναν φαύλο κύκλο και το σύστημα επιβαρύνεται στο σύνολο του.

Αντικαθιστώντας το function call από μία μεταβλητή πετύχαμε πολύ καλύτερα αποτελέσματα.

Το πρόβλημα με τον αλγόριθμο μας είναι ότι έχουμε ακόμα να αντιμετωπίσουμε τους 1535 ελέγχους, πράγμα δύσκολο γιατί πρόκειται για NxM προσέγγιση. Για τα 3 function calls που μείνανε κάτι θα μπορούσαμε να κάνουμε, αλλά μάλλον έχουμε χτυπήσει τοίχο. Αν θέλουμε να κατέβουμε πιο κάτω, θα πρέπει να πλησιάσουμε το πρόβλημα διαφορετικά, αποκλείοντας την NxM προσέγγιση.

DarthMoul
18-07-2004, 16:09
Για τον νέο μας αλγόριθμο, θα χρησιμοποιήσουμε προς όφελος μας, ένα χαρακτηριστικό της γλώσσας C. Στην C, κάθε χαρακτήρας είναι ταυτόχρονα και ακέραιος 8 bit με τιμή ίση με τον ascii του. Με άλλα λόγια οι εντολές:
c=’A’ και c=65 είναι απολύτως ισοδύναμες αφού το 65 είναι ο ascii του κεφαλαίου λατινικού A. Να λοιπόν τι μπορούμε να κάνουμε:

Να δημιουργήσουμε ένα πίνακα 256 ακεραίων που θα τον πούμε ascii με τιμές από το 0 έως το 255. Αυτό γίνεται πολύ απλά έτσι:
for (i = 0; i < 256; i++) ascii[i] = i;

Μετά μπορούμε να αντικαταστήσουμε τις μη έγκυρες τιμές του ascii (αυτές βρίσκονται μέσα στο string invalid) με τις αντίστοιχες έγκυρες (είναι αυτές που βρίσκονται μέσα στο string valid). Να πως θα γίνει:
ilen=strlen(invalid);
for (i=0; i < ilen; i++) ascii[invalid[i]] = valid[i];

Τέλος θα ξαναφτιάξουμε το string που πληκτρολόγησε ο χρήστης χρησιμοποιώντας τον ascii που κατασκευάσαμε εμείς. Μόνο που αυτός ο ascii δεν περιλαμβάνει καθόλου τους μη έγκυρους χαρακτήρες. Bingo! Πάμε να δούμε:
i = 0;
while (string[i] != 0) /* Στην C τα string είναι NULL terminated */
{
string[i] = ascii[string[i]];
i++;
}

Αν μετρήσουμε τους ελέγχους βλέπουμε ότι είναι 256 + 26 + 29 + 1 = 312. Πολύ λιγότεροι από τους 1535 του προηγούμενου αλγορίθμου. Πάμε να το φτιάξουμε και να το μετρήσουμε

DarthMoul
18-07-2004, 16:11
/* convert.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void convert(char *string, char *invalid, char *valid)
{
int ascii[256], ilen, vlen, i;

ilen = strlen(invalid);
vlen = strlen(valid);

/* Το valid και το invalid θα πρέπει να είναι του ιδίου μεγέθους.
Εδώ κάνουμε τον έλεγχο */
if (ilen != vlen)
{
printf("\nconvert: Arguments 2 and 3 are not of the same size. Exiting");
exit(1);
}

/* Εδώ δημιουργούμε τον ascii table */
for (i = 0; i < 256; i++)
ascii[i] = i;

/* Εδώ αντικαθιστούμε τους μη έγκυρους χαρακτήρες τους ascii
με τους έγκυρους */
for (i=0; i < ilen; i++)
ascii[invalid[i]] = valid[i];

/* Εδώ αντικαθιστούμε τους χαρακτήρες τους string
με τους αντίστοιχους από τον ascii */
i = 0;
while (string[i] != 0) /* Στην C τα strings είναι NULL terminated */
{
string[i] = ascii[string[i]];
i++;
}
}

Να και η μέτρηση:
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.082s
user 0m3.073s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.081s
user 0m3.073s
sys 0m0.003s
lucast70@alpha:~/optimize$ time cnvbench

real 0m3.081s
user 0m3.072s
sys 0m0.003s

Και με τον optimizer:
lucast70@alpha:~/optimize$ cc -O2 cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.936s
user 0m0.931s
sys 0m0.003s
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.932s
user 0m0.927s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.933s
user 0m0.929s
sys 0m003s

DarthMoul
19-07-2004, 18:41
Με τον καινούργιο αλγόριθμο πέσαμε κάτω από το ένα δευτερόλεπτο. Αν θέλουμε να πάμε και πιο κάτω υπάρχουν πολλά που θα μπορούσαμε να κάνουμε. Δυστυχώς δεν μπορούμε να τα δείξουμε όλα γιατί το thread έχει γίνει ήδη μεγάλο και κουραστικό. Υπάρχει όμως μια μέθοδος βελτιστοποίησης που είναι δημοφιλής, εύκολη, χρησιμοποιείται ευρύτατα στο technical programming και μπορούμε να την χρησιμοποιήσουμε και εμείς στα προγράμματα μας. Ονομάζεται loop unrolling. Η ελληνική της μετάφραση είναι «ξετύλιγμα του βρόγχου» αν και δεν νομίζω ότι αυτός είναι ο δόκιμος ελληνικός όρος. Πάμε να δούμε πως δουλεύει. Στο παραπάνω πρόγραμμα έχουμε αυτήν την γραμμή:

for (i = 0; i < 256; i++) ascii[i] = i;

Αυτή η γραμμή μπορεί να γραφεί ισοδύναμα ως εξής:

for (i = 0; i < 256; i = i + 4)
{
ascii[i] = i;
ascii[i + 1] = i + 1;
ascii[i + 2] = i + 2;
ascii[i + 3] = i + 3;
}

Τι πετυχαίνουμε με αυτό; Κατ’ αρχήν το loop αντί να κάνει 256 κύκλους, θα κάνει μόνο 64. Άρα θα έχουμε 192 λιγότερες συγκρίσεις και αθροίσεις. Από την άλλη, βοηθάμε τον compiler να κάνει καλύτερο instruction scheduling και να αξιοποιήσει στο μέγιστο την ικανότητα που έχει ο επεξεργαστής μας για out-of-order execution. Το αποτέλεσμα θα είναι να έχουμε περισσότερες από μία εντολές να εκτελούνται ουσιαστικά «εν παραλλήλω».

Το loop unrolling για να εφαρμοστεί έχει την προϋπόθεση να γνωρίζουμε εκ προοιμίου τον αριθμό των κύκλων που θα κάνει το loop, και αυτός ο αριθμός να μην είναι πρώτος. (Υπάρχουν και τεχνικές για να χρησιμοποιήσουμε loop unrolling και με απροσδιόριστο αριθμό κύκλων αλλά θα τις πούμε κάποια άλλη φόρα). Επίσης για να αποδώσει τα μέγιστα θα πρέπει να μην υπάρχει data dependency, δηλαδή να μην χρησιμοποιεί η μία εντολή ως feedback το αποτέλεσμα των υπολογισμών της προηγούμενης. Αν το unroll depth είναι πολύ μεγάλο, θα επιβαρύνουμε το Icache με αποτέλεσμα να μην έχουμε βελτίωση στους χρόνους μας, αλλά επιβάρυνση. Στο παράδειγμα κάναμε unrolling βάθους τεσσάρων επιπέδων. Είναι πολύ καλή επιλογή και θα δουλέψει αποδοτικά σε όλους τους επεξεργαστές που έχουν κατασκευαστεί την τελευταία δεκαετία.

Πάμε να δούμε τον κώδικα και να μετρήσουμε.

DarthMoul
19-07-2004, 18:43
/* convert.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void convert(char *string, char *invalid, char *valid)
{
int ascii[256], ilen, vlen, i;

ilen = strlen(invalid);
vlen = strlen(valid);

if (ilen != vlen)
{
printf("\nconvert: Arguments 2 and 3 are not of the same size. Exiting");
exit(1);
}

/* Εδώ δημιουργούμε τον ascii table και κάνουμε loop unrolling */
for (i = 0; i < 256; i = i + 4)
{
ascii[i] = i;
ascii[i + 1] = i + 1;
ascii[i + 2] = i + 2;
ascii[i + 3] = i + 3;
}

/* Εδώ αντικαθιστούμε τους με έγκυρους χαρακτήρες τους ascii
με τους έγκυρους */
for (i=0; i < ilen; i++)
ascii[invalid[i]] = valid[i];

/* Εδώ αντικαθιστούμε τους χαρακτήρες τους string
με τους αντίστοιχους από τον ascii */
i = 0;
while (string[i] != 0) /* Στην C τα strings είναι NULL terminated */
{
string[i] = ascii[string[i]];
i++;
}
}

Και εδώ είναι η μέτρηση:
lucast70@alpha:~/optimize$ cc cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m2.592s
user 0m2.583s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m2.597s
user 0m2.591s
sys 0m0.001s
lucast70@alpha:~/optimize$ time cnvbench

real 0m2.597s
user 0m2.589s
sys 0m0.004s

Και με χρήση του optimizer:
lucast70@alpha:~/optimize$ cc -O2 cnvbench.c -o cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.740s
user 0m0.734s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.738s
user 0m0.732s
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m0.737s
user 0m0.734s
sys 0m0.002s

DarthMoul
19-07-2004, 19:01
Θα σταματήσουμε εδώ έχοντας σε σχέση με την αρχική προσέγγυση μείωση του χρόνου εκτέλεσης στο 2,36% του αρχικού. Ή με άλλα λόγια 97,64% βελτίωση.

Εσκεμένα απέφυγα να αναφέρω το λειτουργικό, τον compiler και τον επεξεργαστή που χρησιμοποίησα. Ο λόγος είναι ότι ήθελα να δείξω σε γενικές γραμμές μία μεθοδολογία που να είναι εφαρμόσιμη, αποδοτική και ανεξάρτητη όλων αυτών των τεχνικών παραγόντων.

Για τον ίδιο λόγο δεν προχώρησα σε σε system και cpu specific optimizations. Μπορούμε να γράψουμε πραγματικά αποδοτικά προγράμματα και να δώσουμε παραπάνω ζωή στο hardware που έχουμε χωρίς να λύνουμε σπαζοκεφαλιές. Από την άλλη πλευρά αν είμαστε σίγουροι για το hardware που θα τρέξει το πρόγραμμα, αξίζει τον κόπο να αξιοποιήσουμε στο μέγιστο της δυνατότητες του. Σ'αυτήν περίπτωση το παραπάνω πρόγραμμα θα είχε χρόνο εκτέλεσης μικρότερο απο 0.4 sec.

Ελπίζω όσοι είχαν την υπομονή να παρακολουθήσουν το thread να κέρδισαν κάτι και να κατανόησαν την αξία του code optimization. Όσοι θέλουν να κάνουν σχόλια ή ερωτήσεις είναι ευπρόσδεκτοι. Αν υπάρχει ενδιαφέρον, στο μέλλον θα κάνω και outlines διαφόρων μεθόδων βελτιστοποίησης και πρακτικών για την συγγραφή αποδοτικού κώδικα.

DVD_GR
21-07-2004, 00:29
ωραια,για εμας που ειμαστε καπως μακρια απο τη c++ ,μπορουμε να κανουμε κατι αντιστοιχο στη visual basic??

DarthMoul
21-07-2004, 07:52
ωραια,για εμας που ειμαστε καπως μακρια απο τη c++ ,μπορουμε να κανουμε κατι αντιστοιχο στη visual basic??
Φυσικά και μπορείτε. Γίνεται σε όλες τις γλώσσες, με όλα τα λειτουργικά και όλους τους compilers. Σε μερικές μέρες θα ανεβάσω μια σειρά από εύκολα και γρήγορα tips για συγγραφή γρήγορου κώδικα.

doubleh
22-07-2004, 17:33
Να αναφέρω κι εγώ ένα παράδειγμα - όχι τόσο αναλυτικά. Έστω ότι θέλουμε να φτιάξουμε 10χ10 τετραγωνάκια 20χ20 pixels με χρήση της
rectanlge(x,y,mikos,ipsos)
Ο πιο απλός κώδικας είναι
for(i=0;i<10;i++)
for(j=0;j<10;j++)
rectangle(20*i, 20*j, 20, 20);

Λόγω πολλαπλασιασμών - και άμεσης χρήσης των αποτελεσμάτων τους που δεν αφήνει περιθώρια στο pipeline το πρόγραμμα γίνεται τραγικά αργό.
Όταν το έγραψα ως εξής
x=0;
for(i=0;i<10;i++) {
y=0;
for(j=0;j<10;j++) {
rectangle(x,y,20,20);
y+=20;
}
x+=20;
}
η διαφορά ήταν τρομερή. Αυτό οφείλεται στους απαιτούμενους κύκλους που χρειάζεται ο πολ/σμός. Αντίθετα το += γίνεται σε ένα μόνο βήμα. (η κανονική πρόσθεση σε δύο).

MrSeanKon
24-07-2004, 03:16
Υ.Γ. εχεις ενα μικρο λαθακι, ο κωδικας τρεχει μεν, αλλα η συναρτηση "main" επιστρεφει παντα "int"

αρα:

int main(void)
{
...code
return 0;
}

Δεν ειναι απολυτο να δινεις τιμη επιστροφης της main.........
Π.χ. μπορεις καλιστα να γραψεις:

void main(void)
{
κωδικας
}

ή και σκετο

main()
{
κωδικας
}

αλλα η πρωτη μορφη ειναι πιο φορητη (portable) σε ολους τους compilers (UNIX, Borland, Microsoft)....

DarthMoul
25-07-2004, 12:50
Δεν ειναι απολυτο να δινεις τιμη επιστροφης της main.........
Π.χ. μπορεις καλιστα να γραψεις:

void main(void)
{
κωδικας
}

ή και σκετο

main()
{
κωδικας
}

αλλα η πρωτη μορφη ειναι πιο φορητη (portable) σε ολους τους compilers (UNIX, Borland, Microsoft)....

Η πρώτη μορφή ακολουθεί το iso c99 standard. Η δεύτερη το ansi c89. Επειδή δεν μπορώ να ξέρω τι compiler έχει ο καθένας, προτίμησα την ansi c89 για να δουλέψει σε όλους.
Στην ansi c89 το void main θα χτυπήσει παιδιά, γιατί η main δεν μπορεί να έχει τύπο, αντίθετα με την iso c99. Το δεύτερο που έγραψες, κατα το c99 πρότυπο, υπονοεί ότι η main είναι τύπου int.

chaos
16-04-2005, 17:06
Βλεπω οτι τελευταιο Post σε αυτο το thread εγινε αρκετα παλια αλλα επειδη το θεμα ειναι ενδιαφερον θα ηθελα να καταθεσω και τις δικες μου εμπειριες απο τη διαδικασια τις βελτιστοποιησης.
Ολα ξεκινησαν οταν ολοκληρωσα μια εργασια που μας ειχαν βαλει να φτιαξουμε ενα προγραμμα που υπολογιζει πρωτους .Ο χρηστης εισαγει ενα αριθμο και το προγραμμα υπολογιζει ολους τους πρωτους που ειναι μικροτεροι απο αυτον.
Εκεινο που μου εκανε εντυπωση ειναι οτι κατα την εξεταση των εργασιων στο εργαστηριο σχεδον ολοι οι αλγοριθμοι ειχαν διαφορετικη αποδοση η οποια κυμαινοταν απο 5% εως 50%.
Ετσι και εγω βαλθηκα να τροποποιησω τον δικο μου αλγοριθμο ωστε να δινει πολυ γρηγορα αποτελεσμα.
Δυστυχως ο κωδικας των διαδοχικων προγραμματων που ειχα γραψει εχει χαθει.Αυτο ειναι κριμα καθως ειναι εκπληκτικο πως καθε μια μικρη μεταβολη στον κωδικα επηρεαζε την αποδοση.
Πρεπει να αναφερω οτι για τους πρωτους που ειναι μικροτεροι τους 1.000.000 στην αρχη εκανε 2 λεπτα ,μετα 1.5 λεπτο και μετα απο καποια ωρα καθως εξεταζα το προγραμμα μου ηρθε μια ιδεα στο χαρτι για τις ιδιοτητες των διαιρετων καποιων αριθμων και πως αυτο θα επηρεαζε την ταχυτητα εκτελεσης.Οποτε κατεληξα σε αυτον τον κωδικα που ειναι πολυ πιο γραγορος:
//By Chaos 2001-2002
main()
{
register int r, j=1;int n;

printf("",scanf("%d",&n),printf("Enter an integer:"));
do
{
for(r=2;r<=(j/r++); )
if (j%(r++)==0)
r=n;
if (r<n)
printf("%d\n",j);
j+=2;
}while(j<=n);
}

επισης εφτιαξα το προγραμμα και σε πασκαλ για να δω τη διαφορα σε ταχυτητα εκτελεσης σε σχεση με τη C:
program primes(input,output,F);
var i,j:longint;F:text;
ch:char;
function prime(h:longint):boolean;
var d,r:longint;
begin
prime:=true;
r:=3;d:=h div 2;
while (r<=d) do
begin
if ((h mod r)=0) then
begin
prime:=false;
r:=h
end;
d:=h div r;
r:=r+2;
end
end;
BEGIN (* MAIN *)
repeat
assign(F,'Primes.txt');
rewrite(F);
writeln('Welcome!');
writeln('Press i to see some info.');
write(':');readln(ch);
if ch='i' then
begin
writeln('2001-2002 by ChaOs.');
writeln('Press <enter> to continue');
read(ch);
end;
writeln('Enter an integer.');
writeln('Using this integer i will calculate');
writeln('the prime numbers until i reach');
writeln('the integer you entered.');
write(':>');readln(i);
j:=1;
writeln('PRIMES:');
while j<=i do
begin
if j mod 5<>0 then
if (prime(j)) then
begin
writeln(j);
writeln(F,j)
end;
j:=j+2
end;
writeln('Press e and then <Enter> to exit.');
writeln('or any other key to run again.');
writeln('The results are saved in the current directory');
writeln('in the file called primes.txt.');
write(':>');read(ch);
readln;
until ch='e';
close(F)
end.

Επισης αρκετα ενδιαφερον ειναι οχι μονο να μελετησετε τον κωδικα για να καταλαβετε τι κανει αλλα και να κανετε compile τον κωδικα τοσο σε windows οσο και σε linux για να δειτε την διαφορα στους χρονους μεταξυ των δυο λειτουργικων.Επισης αξιολογη ειναι και η διαφορα μεταξυ C και Pascal.

Γενικως για τη διαδικασια της βελτιστοποιησης τιθενται καποια ζητηματα.
1ον Εφοσον τα σημερινα μηχανηματα ειναι πολυ γρηγορα μηπως πια δεν εχει νοημα να βελτιστοποιουμε τα προγραμματα και απλως να εστιαζουμε στην σταθεροτητα του προγραμματος και στα features που θα εχει?
2ονΣυμπληρωματικα ως προς το πρωτο ερχεται μια δηλωση του andrew Tanenbaum ο οποιος υποστηριζει οτι για αυτον πιο σημαντικο ειναι ο προγραμματισμος να γινεται οσο το δυνατο γινεται πιο καθαρα με τελικο κερδος την απολυτη σταθεροτητα παρα την ταχυτητα.
Για να γινω συγκεκριμενος ο καθηγητης Tanenbaum υποστηριζει οτι θα ηταν καλο τα νεα λειτουργικα να γινουν σε micro kernels αρχιτεκτονικη ακομα και αν αυτο σημαινε την υποβαθμιση της αποδοσης των υπολογιστων.
Με βαση μαλιστα υπολογισμους που εκανε η αποδοση των micro kernel λειτουργικων σε σχεση με αυτα μονολιθικου πυρηνα(τα οποια θεωρει ως απαρχαιωμενα τεχνολογικως) θα οδηγουσαν εναν pentium στα 3Ghz να τρεχει ως pentium στα 2.4 Ghz.Θεωρει οτι αρχιτεκτονικες οπως αυτες των μικροπυρηνων παρα την αυξημενη πολυπλοκοτητα των (message passing κτλ) θα προσδωσουν αυξημενη σταθεροτητα και νεες δυνατοτητες στους υπολογιστες παρα το κοστος σε αποδοση.
Αν καποιοι πουν οτι τα windows ειναι micro kernel αρχιτεκτονικη θα παραθεσω μια δηλωση του Torvalds που λεει οτι τα windows ειναι μια ενδιαμεση λυση μεταξυ micro kernel και monolithic kernels και οτι η ομαδα αναπτυξης των windows ουσιαστικα ειχε εγκλωβιστει στο κυριαρχο ρευμα που καποια πολυτεχνεια επεβαλλαν ως ορθο τεχνολογικο δρομο.

Θα ηθελα να δω τις αποψεις σας πανω στο θεμα αυτο παντως.

DarthMoul
16-04-2005, 19:11
Για το πρώτο σου ερώτημα. Είναι σαφές ότι ο βελτιστοποιημένος κώδικας είναι δύσκολα αναγνώσιμος και κατ'επέκταση δύσκολα συντηρήσιμος. Άρα εξαρτάται τι προτεραιότητες έχεις. Και τις προτεραιότητες δεν τις καθορίζει η γνώμη η δική μου, η δική σου ή του Dr. Tanenbaum, με του οποίου τα βιβλία ανατράφηκα, αλλά η ανάγκη. Μια τράπεζα χρειάζεται software εύκολα συντηρήσιμο. Ένα οπλικό σύστημα, ή το ABS του αυτοκινήτου σου ή ο Mars Pathfinder χρειάζονται software γρήγορο.

Το άλλο ερώτημα είναι off topic, και θα προτιμήσω να το απαντήσω αν τεθεί σε αντίστοιχη κατηγορία για τα λειτουργικά συστήματα.

sleeper
29-07-2005, 01:40
Λοιπόν. Να τα πάρουμε με την σειρά και με απλά λόγια. Για να καταλάβουμε τί είναι το High Performance Computing (HPC για συντομία) πρέπει να πούμε πρώτα το είναι το computing, σωστά;
Computing είναι ή χρήση software και hardware για την επίλυση ενός προβλήματος. Είναι αυτό που κάνουμε όλοι μας εδώ. Δεν παίζει ρόλο αν κανείς παίζει παιχνίδια, γράφει στο word, κάνει folding ή τηρεί τα λογιστικά του βιβλία με χρήση υπολογιστή. Όλες αυτές οι διαδικασίες ονομάζονται computing. Η χρήση υπολογιστή γενικότερα ονομάζεται computing.

Τώρα τι είναι το HPC; Υπάρχουν προβλήματα, των οποίων η προσπάθεια επίλυσης προκαλεί ιδιαίτερα υψηλό υπολογιστικό φορτίο. Τέτοια προβλήματα είναι πρόβλεψη που παγκοσμίου κλίματος, η αποκωδικοποίηση του ανθρωπίνου γονιδιόματος, η πρωτεϊνική ανάλυση, η εξομοίωση της πυρινικής σχάσης κλπ. Έτσι λοιπόν, έχουμε ανάγκη για υπολογιστική ισχή πολύ μεγαλύτερη απ'ότι απαιτούν τα συνήθη προβλήματα που επιλύουμε σε καθημερινή βάση. Αρχικά για την επιλυση τους χρησιμοποιούσαμε τεράστιους υπερυπολογιστές και όλη διαδικασία ονομαζόταν supercomputing. Με την πάροδο του χρόνου όμως και την πρόοδο των ηλεκτρονικών το supercomputing κατέστει οικονομικά ασύμφορο και ως πιο δόκιμη λύση εφαρμόστηκε η κλιμάκωση commodity hardware, δηλαδή του ίδιου hardware που χρησιμοποιούμε και εμείς στα σπίτια μας ή σχεδόν του ίδιου. Έτσι λοιπόν γεννηθηκαν οι superclusters που χρησιμοποιούνται σήμερα ευρέως για την λύση προβλημάτων με πολύ υψηλές υπολογιστικές απαιτήσεις. Αν συνδιάσετε τους superclusters με προγραμματιστικές μεθόδους που έχουν σκοπό την όσο το δυνατόν μεγαλύτερη αξιοποίηση τους, τότε έχετε το HPC. Το code optimization που μας είπε παραπάνω ο Linos είναι η σημαντικότερη παράμετρος από πλευράς software για την αξιοποίηση τέτοιων συστημάτων. Όλες οι μέθοδοι βελτιστοποίησης κώδικα πρώτα ανακαλύπτονται και δοκιμάζονται σε τέτοια συστήματα γιατί εκεί υπάρχει η επιτακτική ανάγκη για κάτι τέτοιο. Από πλευράς hardware o πιο σημαντικός παράγοντας είναι η δυκτίωση.

Παλιότερα οι αναφορές ήταν στο High Performance Technical Computing (HPTC) αλλά τα τελευταία χρόνια ο όρος technical αποφεύγεται γιατί υπάρχουν και προβλήματα μη τεχνικής φύσεως που έχουν ανάγκη από high performance clusters για την επίλυση τους.
Τώρα θα μου πείτε, και τι μας νοιάζει εμάς εδώ όλη αυτή η ιστορία. Καταρχήν οι superclusters είναι η Formula 1 των υπολογιστών και μπορείτε να τους δείτε εδώ: http://www.top500.org Αφού έχουμε το ψώνιο, μας νοιάζει!!!
Και φυσικά αφού χρησιμοποιούν το ίδιο hardware που έχουμε και εμείς στα σπίτια μας ή στις δουλειές μας, μπορούμε να χρησιμοποιήσουμε πολλές από τις μεθόδους βελτιστοποίησης που χρησιμοποιούν εκεί κάνοντας τις εφαρμογές μας να πετάνε. Αυτό προϋποθέτει πως το πρόγραμμα το έχουμε γράψει εμείς ή ότι έχουμε τα sources. Σε αντίθετη περίπτωση, η άλλη επιλογή που έχουμε είναι το overclocking. Το code optimization βέβαια έχει το πλεονέκτημα ότι δεν βάζει σε κανέναν κίνδυνο το σύστημα μας και δεν προκαλεί κόστος. Και την προϋπόθεση ότι γνωρίζουμε καλά τουλάχιστον μία γλώσσα προγραμματισμού. Τέλος, αν μπούμε στην διαδικασία αναγκαζόμαστε να κατανοήσουμε πως λειτουργεί η μηχανή "από μέσα" και ανακαλύπτουμε τεχνικές λεπτομέριες και διαφορές μεταξύ αρχιτεκτονικών που σε άλλη περίπτωση θα μας διέφευγαν. Αυτό θα μας βοηθήσει σε μελλοντικές επιλογές hardware ανάλογα με τις ανάγκες μας. Και φυσικά έχει και πλάκα, ειδικά όταν ανακαλύπτουμε την ποιότητα και τις αδυναμίες του software που κάποιες εταιρίες μας πουλάνε πανάκριβα :110:

hello

sorry για το τρόπο που θα βάλω τα post μου αλλα δεν βρήκα trop να βάλω quote σε πάνω από ένα post... τέλος πάντων άμα υπάρχει πείτε μου :D

λοιπόν έχω να σχολιάσω τα εξής:
πρώτον άλλο το HPC και άλλο ο υπερυπολογιστής...το έχω ψάξει αρκετά το θέμα γιατί ήταν να κάνω master πάνω στα HPC και μετά από ένα "ατύχημα" έκανα master στα embeded :P λοιπόν το HCP είναι ένα cluster που αποτελείται από ξεχωριστές αυτόνομες μονάδες... δηλαδή για παράδειγμα το πρώτο beowolf (νομίζω έτσι γράφετε) που ανέπτυξε η nasa χρησιμοποίηση κάμποσα pc για να κάνει τι δουλειά του... σε σημερινά συστήματα αυτό το κάμποσα μεταφράζεται σε κάμποσες χιλιάδες...
το θέμα είναι ότι οι υπερυπολογιστές είναι διαφορετικοί... στον υπερυπολογιστή έχεις ένα σύστημα με πολλούς επεξεργαστές... και όπως καταλαβαίνετε η διαφορα είναι ότι στο supercomputer μιλάμε για ένα σύστημα όχι πολλά αυτόνομα που συνεργάζονται...
τα supercomputer δεν μας ενδιαφέρουν πρακτικά γιατί δεν μπορούμε να τα έχουμε σπίτι μας...
ας πάρουμε τα HPC που μπορούμε να τα κάνουμε σπίτι μας... εκεί μπορούμε να παίξουμε με διαφορους τρόπους... ο ποιο εύκολος είναι να κάνουμε το load balance με το να στέλνει το ένα pc όλη την εφαρμογή σε ένα άλλο pc να την τρέξει και να στειλει πίσω τα αποτελέσματα... ο άλλος τρόπος και ποιο δύσκολος είναι να τρέχει η εφαρμογή σε πολλά pc ταυτόχρονα...

όπως και να έχει όμως δεν μπορούμε να μιλήσουμε για code optimization γιατί πολύ απλά στην πρώτη περίπτωση ο κώδικας είναι ο ίδιος και το λειτουργικό αναλαμβάνει να κάνει το νταλαβέρι... και στη δεύτερη περίπτωση θα έλεγα ότι ο μονος τρόπος για να το κανεις είναι να ξαναγράψεις όλο το πρόγραμμα με τρόπο που να μπορεί να χρησιμοποίηση τα κατάλληλα libraries για να γίνει η όλη δουλειά ;)

Chris

apotsi
29-07-2005, 01:46
Φίλε Chris, γράφε με ελληνικά. Δοκίμασε να κάνεις edit το post σου και να χρησιμοποιήσεις τον Greeklish converter αν δυσκολεύεσαι με τα ελληνικά.

Διάβασε τους κανόνες και τα PM σου.
http://www.pctechnology.gr/vbull/vb/faq.php?
http://www.pctechnology.gr/vbull/vb/private.php?

Καλωσήρθες στο site μας.

sleeper
29-07-2005, 01:48
Ο φιλος Darthmoul εχει απολυτο δικιο.
Πραγματικα με το overclocking 8α κερδισεις ισως ενα μικρο ποσοστο στην αποδοση ενω με την βελτιστοποιηση ενος κωδικα και την δημιουργια ενος πιο <<εξυπνου>> αλγοριθμου μπορεις να κερδισεις 10πλασιες φορες σε χρονο εκτελεσης.
Το γεγονος αυτο βεβαια δεν περιοριζει κανενας μας να βρισκουμε τα ορια των μηχανηματων μας σε επιπεδο hardware αλλα φυσικα θα ηταν ευχης εργο να ειχαμε στην ομαδα μας ανθρωπους που ασχολουνται με optimization σε επιπεδο software ωστε να κανουμε κι εκει τις αναλυσεις μας και να βγαλουμε τα συμπερασματα μας!!! :038:
το κέρδος από τον υπερχρονισμός είναι iso πρακτικα με το ποσοστο της αύξησης του ρολογιού... αν για παράδειγμα αύξησης το ρολοι 10% θα πάρεις και 10% κέρδος... στο code optimization μπορείς να κερδίσεις περισσότερα... αλλα μπορείς να χάσεις κιόλας...
ας πούμε για παράδειγμα ότι κανεις μαθηματικές πράξις... μπορείς να inline assembly και από εκεί που μια ρουτίνα είχε 20 εντολές (instructions) να έχει 2... τότε κέρδισες... αλλα θα μπορούσες να κανεις και έναν πινακα που να αποθηκεύονται αποτελέσματα και να τα χρησιμοποιείς από εκεί άμα τα χρειαστείς αντί να τα ξαναυπολογιζεις... και πάλι κέρδισες σε χρόνο αλλα έχασες σε μνήμη :P

sleeper
29-07-2005, 01:50
Φίλε Chris, γράφε με ελληνικά. Δοκίμασε να κάνεις edit το post σου και να χρησιμοποιήσεις τον Greeklish converter αν δυσκολεύεσαι με τα ελληνικά.

Διάβασε τους κανόνες και τα PM σου.
http://www.pctechnology.gr/vbull/vb/faq.php?
http://www.pctechnology.gr/vbull/vb/private.php?

Καλωσήρθες στο site μας.

υπάρχει ένα μικρό πρόβλημα... δεν μπορώ να γράψω με ελληνικούς χαρακτήρες... :D

edit: το βρήκα και το άλλαξα ;)

by the way καλός σας βρήκα

sleeper
29-07-2005, 01:57
καλη φαση αδελφε, αλλα...
ο κωδικας μπορει να ειναι μικρος μεν , αλλα μην ξεχνας πως δεν τον εχουμε γραψει εμεις. που συμενει πως μερικες σημειωσεις διπλα απο τον κωδικα δεν θα ηταν ασχημες.

ΥΓ. εχεις ενα μικρο λαθακι, ο κωδικας τρεχει μεν, αλλα η συναρτηση "main" επιστρεφει παντα "int"

αρα:

int main(void)
{
...code
return 0;
}

δεν είναι απαραίτητο... μπορείς να μην επιστρέψεις τίποτα (δεν θα βάλεις return) και να το παραλείψεις... δημιουργώντας αλλα πρόβλημα αλλα δεν είναι λάθος να το κανεις...

Chris

sleeper
29-07-2005, 02:04
Για να το σκεφτούμε λιγάκι το ζήτημα. Για 300000 ελέγχους, δηλαδή όσα τα records της βάσης μας θέλουμε περίπου 30''. Επί 20 χρήστες και αυτό επί 6 φορές την ώρα πέρνουμε το μαγικό νούμερο 3600 δευτερόλεπτα. Δηλαδή όσα ακριβώς είναι τα δευτερόλεπτα μιας ώρας. Με άλλα λόγια, το σύστημα μας θα απασχολείται 100 μόνο με αυτή την διαδικασίας. Και φυσικά δεν είναι αυτή η μόνη δουλειά που έχει να κάνει ο server μας. Και όποιος πάει στο αφεντικό να του πει πως πρέπει να αγοράσουμε καινούργιο server μάλλον η απάντηση θα είναι αυτή :021:

Για να κάνουμε μια δοκιμή με τον "οπτιμιζερ" του compiler να δούμε τι έχει να μας δώσει:

lucast70@alpha:~/optimize$ cc -Ο2 cnvbench.c -ο cnvbench
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.146σ
user 0m22.004σ
sys 0m0.004s
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.141s
user 0m22.006s
sys 0m0.002s
lucast70@alpha:~/optimize$ time cnvbench

real 0m22.141s
user 0m22.004σ
sys 0m0.003s

Σχεδόν 30 βελτίωση. Καλό αλλά λίγο. Και πάλι το σύστημα θα απασχολείται κατά 70 γι αυτήν την αστεία μεν αλλά αναγκαία διαδικασία

γιατί δεν χρησιμοποίησες -Ό3???? εκεί είναι όλο το ζουμί.... το -Ο2 ναι μεν κάνει βελτιστοποίηση του κώδικα αλλα προσέχει να είναι και κάπως μικρός... το -Ό3 τα δίνει όλα για την βελτιστοποίηση... ;)

Chris

sleeper
29-07-2005, 02:20
Με τον καινούργιο αλγόριθμο πέσαμε κάτω από το ένα δευτερόλεπτο. Αν θέλουμε να πάμε και πιο κάτω υπάρχουν πολλά που θα μπορούσαμε να κάνουμε. Δυστυχώς δεν μπορούμε να τα δείξουμε όλα γιατί το thread έχει γίνει ήδη μεγάλο και κουραστικό. Υπάρχει όμως μια μέθοδος βελτιστοποίησης που είναι δημοφιλής, εύκολη, χρησιμοποιείται ευρύτατα στο technical programming και μπορούμε να την χρησιμοποιήσουμε και εμείς στα προγράμματα μας. Ονομάζεται loop unrolling. Η ελληνική της μετάφραση είναι «ξετύλιγμα του βρόγχου» αν και δεν νομίζω ότι αυτός είναι ο δόκιμος ελληνικός όρος. Πάμε να δούμε πως δουλεύει. Στο παραπάνω πρόγραμμα έχουμε αυτήν την γραμμή:

for (i = 0; i < 256; i++) ascii[i] = i;

Αυτή η γραμμή μπορεί να γραφεί ισοδύναμα ως εξής:

for (i = 0; i < 256; i = i + 4)
{
ascii[i] = i;
ascii[i + 1] = i + 1;
ascii[i + 2] = i + 2;
ascii[i + 3] = i + 3;
}

Τι πετυχαίνουμε με αυτό; Κατ’ αρχήν το loop αντί να κάνει 256 κύκλους, θα κάνει μόνο 64. Άρα θα έχουμε 192 λιγότερες συγκρίσεις και αθροίσεις. Από την άλλη, βοηθάμε τον compiler να κάνει καλύτερο instruction scheduling και να αξιοποιήσει στο μέγιστο την ικανότητα που έχει ο επεξεργαστής μας για out-of-order execution. Το αποτέλεσμα θα είναι να έχουμε περισσότερες από μία εντολές να εκτελούνται ουσιαστικά «εν παραλλήλω».

Το loop unrolling για να εφαρμοστεί έχει την προϋπόθεση να γνωρίζουμε εκ προοιμίου τον αριθμό των κύκλων που θα κάνει το loop, και αυτός ο αριθμός να μην είναι πρώτος. (Υπάρχουν και τεχνικές για να χρησιμοποιήσουμε loop unrolling και με απροσδιόριστο αριθμό κύκλων αλλά θα τις πούμε κάποια άλλη φόρα). Επίσης για να αποδώσει τα μέγιστα θα πρέπει να μην υπάρχει data dependency, δηλαδή να μην χρησιμοποιεί η μία εντολή ως feedback το αποτέλεσμα των υπολογισμών της προηγούμενης. Αν το unroll depth είναι πολύ μεγάλο, θα επιβαρύνουμε το Icache με αποτέλεσμα να μην έχουμε βελτίωση στους χρόνους μας, αλλά επιβάρυνση. Στο παράδειγμα κάναμε unrolling βάθους τεσσάρων επιπέδων. Είναι πολύ καλή επιλογή και θα δουλέψει αποδοτικά σε όλους τους επεξεργαστές που έχουν κατασκευαστεί την τελευταία δεκαετία.

Πάμε να δούμε τον κώδικα και να μετρήσουμε.

εγώ είμαι πάλι :D

λοιπόν το loop unrolling δεν χρειάζεται να το κανεις εσύ άμα βάλεις παράμετρο -ΌΚΣ στον gcc είμαι 90 σίγουρος ότι θα στο κάνει αυτός...
το κέρδος βασικά στην υπόθεση είναι πολύ μεγαλύτερο από αυτό που περιγράφεις... άμα έχεις "λιγοτες" συγκρίσεις και jump στον κώδικα σου δεν κινδυνεύεις να βλάλη λάθος ο μηχανισμός πρόβλεψης αν θα πηδήξεις ή όχι στο jump... άμα το πετύχει τότε όλα είναι ένταξη δεν έχασες τίποτα, απλά έτρεξες μια εντολή παραπάνω... άμα δεν το πετύχει τότε την πάτησες... έχεις βάλει λάθος εντολές στο pipeline και πρέπει να το αδειάσεις... το κόστος αυτής τις αποτυχίας εξαρτάται από το ποσο βάθη είναι το pipeline...(νομίζω ότι οι P4 έχει 32 εντολές στο pipeline οποτε ένα άδειασμα σου κοστίζει 32 εντολές)

οποτε 2 εντολές που γλιτώνεις δεν είναι τίποτα μπροστά στις 32 ;)

Chris

sleeper
29-07-2005, 02:52
...
2ονΣυμπληρωματικα ως προς το πρωτο ερχεται μια δηλωση του andrew Tanenbaum ο οποιος υποστηριζει οτι για αυτον πιο σημαντικο ειναι ο προγραμματισμος να γινεται οσο το δυνατο γινεται πιο καθαρα με τελικο κερδος την απολυτη σταθεροτητα παρα την ταχυτητα.
...


το να γράψεις καθαρό και σταθερό κώδικα είναι πολύ ποιο σημαντικό από το να γράψεις γρήγορο κώδικα... γιατί στην τελική ο gcc θα στον κάνει γρήγορο... αλλα άμα μετά από ένα μηνα δεν καταλάβεις τι έχεις γράψει τότε την πάτησες... ;) όσο για την σταθερότητα... τι σημασία έχει ποσο γρήγορος κώδικας είναι άμα κολλάει ή βγάζει λάθος αποτελέσματα...

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

πρακτικά ο τρόπος που κανεις σωστή και "επαηγκελματικι" βελτιστοποίηση είναι πρώτα να κοιτάξεις την ιδέα του αλγοριθμου να δεις άμα είναι η ποιο γρηγορη... μετά να κοιτάξεις την υλοποίηση του αλγοριθμου να δεις άμα είναι σωστή/γρηγορη... και τέλος να πάρεις έναν profiler και να δεις πια function καλούνται τις περισσότερες φορες και περνούν το περισσότερο χρόνο για να βελτιώσεις για την συγκεκριμένη πλατφόρμα(hardware)

για παράδειγμα βλέπουμε ότι στην συγκεκριμένη υλοποίηση έχει 2 πίνακες έναν με τους σωστούς χαρακτήρες και έναν με τους λάθος... και κοιτάει άμα ο χαρακτήρας είναι σωστός ή λάθος...(αυτό κατάλαβα αν και δεν κοίταξε προσεχτικά το κώδικα γιατί με αρκετό κώδικα ασχολήθηκα σήμερα όλη τι μέρα... :D)
για μένα αυτή η ιδέα είναι λάθος εξαρχής... και έπρεπε να αλλάξει στο πρώτο βήμα τις βελτιστοποίησης... διότι αφού ξέρουμε ότι πρέπει να είναι κεφαλές οποτε πρέπει να είναι μεγαλύτερο ή iso του A και μικρότερο ή iso του Z άρα μπορούμε να γράψουμε"


if (input >= 'A' && input <='Z')
{
do stuff;
}

οποτε γλιτώνουμε όλο το κόπο.... ;)

Chris

DarthMoul
29-07-2005, 07:47
if (input >= 'A' && input <='Z')
{
do stuff;
}

οποτε γλιτώνουμε όλο το κόπο.... ;)

Chris
Φίλε μου το δοκίμασα αυτό που λες. Δυστυχώς βγαίνει πιο αργό αφού το if που έβαλες υποχρεωτικά θα εκτελείται πολλαπλά σε μια πραγματική περίπτωση. Με τον δεύτερο τρόπο που χρησιμοποιώ εγώ, την αντικατάσταση των invalid ascii values με τις valid, αποφεύγεις τις συγκρίσεις πλήρως.

Όσον αφορά το unrolling που κάνει ο gcc, μάλλον σου διαφεύγει το γεγονός ότι δεν έχουν όλοι gcc. Το δε profiling αναφέρω στην αρχή πως θα το κάνω με το χέρι για να το δείξω στην πράξη, αλλά τελικά θα πρέπει να χρησιμοποιούμε profiler.

Για τα trade-offs του code optimization αναφέρομαι και στην αρχή. Επίσης για την διαφορά μεταξύ super-computer και super-cluster θα βρεις παλαιότερα threads.

sleeper
29-07-2005, 08:56
Φίλε μου το δοκίμασα αυτό που λες. Δυστυχώς βγαίνει πιο αργό αφού το if που έβαλες υποχρεωτικά θα εκτελείται πολλαπλά σε μια πραγματική περίπτωση. Με τον δεύτερο τρόπο που χρησιμοποιώ εγώ, την αντικατάσταση των invalid ascii values με τις valid, αποφεύγεις τις συγκρίσεις πλήρως.

Όσον αφορά το unrolling που κάνει ο gcc, μάλλον σου διαφεύγει το γεγονός ότι δεν έχουν όλοι gcc. Το δε profiling αναφέρω στην αρχή πως θα το κάνω με το χέρι για να το δείξω στην πράξη, αλλά τελικά θα πρέπει να χρησιμοποιούμε profiler.

Για τα trade-offs του code optimization αναφέρομαι και στην αρχή. Επίσης για την διαφορά μεταξύ super-computer και super-cluster θα βρεις παλαιότερα threads.

όντως θα πρέπει να εκτελεστή πολλές φορες... και για την ακρίβεια θα πρέπει να εκτελεστή φορες ίσες με το μέγεθος του string... αλλα κάθε φορα θα κάνει μονο 2 συγκρίσεις... δεν ξέρω βεβαια σε assembly τι βγάζει γιατί το <= και >= είναι πρακτικά 2 σύγκρισης το καθένα... βάλε και κάνα jump που θα έχει μέσα... πάντως θα το κοιτάξω να δω τι παίζει με το gdb για να δω πως ακριβώς θα δουλέψει το καθένα... αλλα το θεωρώ τουλάχιστον απίθανο 2 for το ένα μέσα στο άλλο και ένα if στη μέση να είναι ποιο αργό από ένα if με τόσο πολύπλοκη σύγκριση...

όσο για το ότι δεν έχουν όλοι gcc... ας πρόσεχαν... linux rules... :P

DarthMoul
29-07-2005, 10:16
όντως θα πρέπει να εκτελεστή πολλές φορες... και για την ακρίβεια θα πρέπει να εκτελεστή φορες ίσες με το μέγεθος του string... αλλα κάθε φορα θα κάνει μονο 2 συγκρίσεις... δεν ξέρω βεβαια σε assembly τι βγάζει γιατί το <= και >= είναι πρακτικά 2 σύγκρισης το καθένα... βάλε και κάνα jump που θα έχει μέσα... πάντως θα το κοιτάξω να δω τι παίζει με το gdb για να δω πως ακριβώς θα δουλέψει το καθένα... αλλα το θεωρώ τουλάχιστον απίθανο 2 for το ένα μέσα στο άλλο και ένα if στη μέση να είναι ποιο αργό από ένα if με τόσο πολύπλοκη σύγκριση...

όσο για το ότι δεν έχουν όλοι gcc... ας πρόσεχαν... linux rules... :P
Σε παρακαλώ μην βγαίνεις έξω από το πνεύμα του thread. Τα tips είναι γενικής χρήσης. Αν θέλεις να γράψεις για platform/compiler specific μπορείς να ανοίξεις ένα και να το κουβεντιάσουμε εκεί.

Μια πραγματική περίπτωση θα ήταν στον έλεγχο των πεδίων ενός database connection form. Στην δεύτερη περίπτωση που δίνω εγώ έχει απείρως λιγότερα if σε σχέση με αυτό που προτείνεις. Αντι να κουβεντιάζουμε θεωρητικά γράψε κώδικα και κάνε compile και δοκιμή.

sleeper
29-07-2005, 22:32
Σε παρακαλώ μην βγαίνεις έξω από το πνεύμα του thread. Τα tips είναι γενικής χρήσης. Αν θέλεις να γράψεις για platform/compiler specific μπορείς να ανοίξεις ένα και να το κουβεντιάσουμε εκεί.

Μια πραγματική περίπτωση θα ήταν στον έλεγχο των πεδίων ενός database connection form. Στην δεύτερη περίπτωση που δίνω εγώ έχει απείρως λιγότερα if σε σχέση με αυτό που προτείνεις. Αντι να κουβεντιάζουμε θεωρητικά γράψε κώδικα και κάνε compile και δοκιμή.

proton: δεν βγαίνω έξω από το θέμα του thread γιατί πρακτικά το θέμα είναι optimization και όχι HCP ;) και θα καταλάβεις γιατί δεν βγαίνω όταν δεις τα αποτελέσματα...

δεύτερον είναι απλή C, άμα θες να στο κάνω compile και να το τρέξω και σε άλλες πλατφόρμες, μπορώ να το κάνω την επομενη παρασκευή που θα "σκαναπαω" στο εργαστήριο... η επιλογές σου είναι οι εξής: Dual Ξέων, Dual Core P4,απλός P4, Συν, ARM αν θέλεις να δεις τα αποτελέσματα σε κάποια από αυτές τις πλατφόρμες πες μου και θα τα κάνω post...

τρίτον: δουλειά μου αυτή τι στιγμή είναι να κάνω optimization ένα πρόγραμμα για embedded... οποτε καταλαβαίνεις ότι μπορώ να μειώσω και άλλο το χρόνο για το δικό μου αλλα θα γίνει platform specific και δεν έχει νόημα...

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

κώδικας:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(void){
char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char invalid[] = "abcdefghijklmnopqrstuvwxyz";
char string[]= "abc";

int i,j,k,ilen,slen;

ilen = strlen(invalid);
slen = strlen(string);

i=0;
j=0;
k=0;

for (k=0; k<10000000;k++){
/*
for(i=0; i<ilen; i++)
for(j=0; j<slen; j++)
if (invalid[i] == string[j]) {

string[j] = valid[i];
}
*/

for (i=0;i<slen;i++){

if((string[i]>=97) && (string[i]<=122)){
string[i]-=32;
}
}



αποτελέσματα πρότασης μου:
flag -s (opt στο μέγεθος του αρχείου):
real 0m0.541s
user 0m0.477s
sys 0m0.002s

flag -O3:
real 0m0.325s
user 0m0.283s
sys 0m0.002s

αποτελέσματα πρότασης σου:
flag -s:
real 0m6.012s
user 0m5.657s
sys 0m0.035s

flag -O3:
real 0m2.631s
user 0m2.455s
sys 0m0.004s

η δοκιμη έγινε σε έναν AMD64 με μητρική Asus K8N-E Ντελούξ

Chris

DarthMoul
29-07-2005, 23:03
Η υπόθεση ότι η διαφορά μεταξύ των χαρακτήρων θα είναι πάντα σταθερή (πχ 32) είναι παρακινδυνευμένη. Αν την επόμενη φορά χρειαστεί να μετατρέψεις ελληνικά από 437 σε 928 που η διαφορά μεταξύ των χαρακτήρων είναι μεταβλητή και ακανόνιστη θα αναγκαστείς να γράψεις άλλη. Σε real life application (όχι παραδειγματάκια όπως εδώ) αυτά δεν γίνονται γιατί ανεβάζουν το κόστος στα ύψη.

Μόνο αν ήμουν εντελώς σίγουρος ότι σε κάθε περίπτωση που θα έχω μια σταθερή διαφορά, όπως εδώ είναι το 32, θα την έφτιαχνα έτσι. Και πάλι δεν θα την έφτιαχνα σε C αλλά σε assembly για να κατέβω κι άλλο.

sleeper
29-07-2005, 23:44
και η 2 προτάσεις δεν ενδείκνυται για πραγματική εφαρμογή (με αυτές τις προδιαγραφές)... στην πραγματικότητα θα το μετέτρεπες με την function τις C υπάρχει function να μετατρέψει ένα string από μικρά σε κεφαλές ή το αντίθετο... αλλα ακόμα και έτσι να είναι... δεν είναι δικό σου πρόβλημα... αφού σου ζήτησαν να το κανεις με λατινικούς χαρακτήρες ας πρόσεχαν... ali φορα να προσέχουν τι ζητάνε ή να πληρώνουν για αλλαγές
mouahahahahahahahaha ;)
εσύ κέρδος θα έχεις γιατί θα πάρεις παραπάνω δουλειά ;)

Chris

DarthMoul
30-07-2005, 10:32
Η προδιαγραφή είναι πάντα να κατασκευάζεις όσο πιο γενικής χρήσης συναρτήσεις μπορείς με τις μεγιστες επιδόσεις ώστε να μειώνεις το κόστος συντήρησης του κώδικα σου. Έτσι κερδίζεις πολύ περισσότερα από ότι με την ελληνικής νοοτροπίας προσέγγυση και τα επιφωνήματα που μου περιγράφεις πιο πάνω. Κάποια στιγμή θα χρειαστείς την αντιστοίχηση "ΝΞχΤΦΚΛΠΔ" σε "7&KL90JI" ή κάτι ανάλογο. Εκεί δεν θα σε καλύψει ούτε η συνάρτηση της C ουτε αυτό που έφτιαξες. Θα αναγκαστείς να τα ξαναφτιάξεις. Ενδεχομένως κάτω από πίεση χρόνου. Αν δοκιμάσεις να το φτιάξεις θα δεις ότι τελικά θα καταλήξεις σε αυτό που έφτιαξα και εγώ.

Για να τελειώνει η ιστορία εδώ, η προσέγγυση που έδειξα παραπάνω είναι η υλοποίηση της εντολής INSPECT CONVERΤING ενός compiler cobol όπως φτιάχτηκε πριν από 15 χρόνια περίπου. Ο κώδικας αυτός χρησιμοποιήται ακόμα και σήμερα ανέπαφος για τον πολύ απλό λόγο ότι καλύπτει όλες τις περιπτώσεις σε πολύ γρήγορους χρόνους. Δεν χρειάστηκε να τον αγγίξουν καν παρόλο που το προϊόν έχει βγάλει αρκετές versions μέχρι σήμερα. Αυτή είναι η έννοια του overengineered software η οποία τους περισσότερους σίγουρα δεν τους αφορά.

sleeper
30-07-2005, 23:00
εξαρτάται το backround σου... άμα ίσια από κανονικό software engineering τότε ναι... σε νοιάζει να μπορείς να το τρέχεις για πολύ καιρό με ελάχιστες αλλαγές... αλλα άμα είσαι από embedded engineering όπως εγώ τότε δεν είναι έτσι... τα δίνεις όλα για να κερδίσεις έναν κύκλο ρολογιού ή μερικές χιλιάδες transistor στο τσιπάκι του προϊόντος... μην ξεχνάς ότι εκεί που χρειάζεται το optimization δεν είναι στα pc αλλα σε συσκευές που έχουν ελαχιστη επεξεργαστική ισχύ για λόγους κόστους και κατανάλωσης... μια εταιρία προτιμάει να τις κοστίσει μισό ευρώ λιγότερο το hardware τις συσκευής όταν θα πουλήσει χιλιάδες συσκευές από το να έχει κώδικα που να μπορεί να τον ξαναχρησιμοποιήσει... το θέμα είναι η στρατηγική... design for reuse i' disign for performance... ;)

Chris

DarthMoul
31-07-2005, 02:08
Μιλάς για 1% ή κάτι ανάλογο που είναι το ποσοστό του κώδικα που γράφεται για embedded επεξεργαστές. Μόνο αντιπροσωπευτικό δεν μπορεί να είναι. Από την άλλη ο κώδικας που γράφεται για τέτοιες μηχανές έχει ελάχιστη διάρκεια ζωής λόγω της ταχύτατης εξέλιξης τους.

Ακόμα και ο reusable κώδικας για PCs μπορεί να είναι optimized. Με εκπληκτικά αποτελέσματα λόγω πληθώρας συσκευών που έχουν διαφορετικά χαρακτηριστικά η κάθε μία. Στις embedded συσκευές το optimization εξαντλήται μεταξύ cpu και μνήμης. Οι πιο πολλές ούτε cache δεν έχουν, άρα δεν υπάρχει και το κεφάλαιο cache efficient κώδικας που είναι από τα πλεόν σημαντικά. Είναι καλές περιπτώσεις για να κάνει κανείς το ξεκίνημα του στο code optimization, αλλά εκεί τελειώνει και το παραμύθι. Και εγώ έτσι ξεκίνησα να ασχολούμαι με το θέμα πριν 13 χρόνια. Με κάτι φορητά τερματικά της Telxon, τα PTC. Οπότε καταλαβαίνω πολύ καλά τι λες.

sleeper
31-07-2005, 03:48
δεν θα έλεγα ότι είναι μονο το 1 του καινούριου κώδικα που γράφετε... ίσος να είναι λιγότερο από 1 του κώδικα που υπάρχει αλλα σίγουρα είναι πάνω από το 90 που γράφετε σήμερα... και πολύ απλά γιατί τα pc όλα χρησιμοποιούν τα ίδια προγράμματα πάνω κάτω... όμως αυτοί που έχουν embedded συσκευές είναι πολύ περισσότεροι από αυτούς που έχουν pc... σκέψη πόση έχουν κίντα τηλεφωνα και παρόμοιες συσκευές, φούρνους μικροκυμάτων... γκούτερ, μέχρι και οι "αδιρματες" κάρτες "δικριων" (οι περισσότερες) είναι embedded σύστημα... πριν να ασχοληθώ νόμιζα ότι ήταν λίγες οι συσκευές... τώρα παντού βλέπω embedded... :D
όσο για το χρόνο που λες... ακριβώς το αντίθετο... κανεις δεν θέλει να φτιάξει έναν "δοριφοτο" που να σταματήσει να δουλεύει και ούτε πρόκειται να τον αναβάθμιση... ούτε θες να βάλεις έναν αισθητήρα στην ανταρτικη και να τελειώσει από μπαταρία επειδή τρέχει 10 εντολές παραπάνω ;)

DarthMoul
31-07-2005, 06:26
Αν είναι έτσι όπως τα λες, θα πρέπει να υπάρχουν τουλάχιστον δεκαπλάσιοι developers για φορητές συσκευές από ότι για pc's ή μεγαλύτερες. Αν θέλεις κάνε ένα search στο google και πες μου τι βρήκες. Ακόμα και αν μετρήσεις ώς developers τους κατασκευαστές, που όντως είναι και software developrs για τις συσκευές τους τις περισσότερες φορές, μάλλον θα απογοητευτείς από τα νούμερα που θα δεις.

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

Δεν ξέρω πόσο software για δορυφόρους έχεις γράψει εσύ; Εγώ δεν έτυχε πάντως τόσα χρόνια. Σε κάθε νέα έκδοση του ptc, κάθε 6-12 μήνες περίπου, που ερχόταν ριζικά εμπλουτισμένη με RF, Pen based device, bar code readers, ή touch pads τελικά έπρεπε να ξαναγράψεις τουλάχιστον τα μισά, και να προσθέσεις πολλά ακόμα.

Τίποτα δεν σταμάταγε να δουλεύει. Ούτε έπεφταν οι μπαταρίες. Απλά η επόμενη έκδοση της συσκευής επέβαλε να ξαναγραφτούν σχεδόν τα πάντα. Ο παλιός κώδικας ήταν ουσιαστικά άχρηστος ή ασύμφορος μετά από 1-2 χρόνια το πολύ. Φαντάζεσαι να ίσχυαν τα ίδια για την Oracle; Ο Larry Elison θα είχε γίνει ζητιάνος.

sleeper
06-08-2005, 15:10
Αν είναι έτσι όπως τα λες, θα πρέπει να υπάρχουν τουλάχιστον δεκαπλάσιοι developers για φορητές συσκευές από ότι για pc's ή μεγαλύτερες. Αν θέλεις κάνε ένα search στο google και πες μου τι βρήκες. Ακόμα και αν μετρήσεις ώς developers τους κατασκευαστές, που όντως είναι και software developrs για τις συσκευές τους τις περισσότερες φορές, μάλλον θα απογοητευτείς από τα νούμερα που θα δεις.

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

Δεν ξέρω πόσο software για δορυφόρους έχεις γράψει εσύ; Εγώ δεν έτυχε πάντως τόσα χρόνια. Σε κάθε νέα έκδοση του ptc, κάθε 6-12 μήνες περίπου, που ερχόταν ριζικά εμπλουτισμένη με RF, Pen based device, bar code readers, ή touch pads τελικά έπρεπε να ξαναγράψεις τουλάχιστον τα μισά, και να προσθέσεις πολλά ακόμα.

Τίποτα δεν σταμάταγε να δουλεύει. Ούτε έπεφταν οι μπαταρίες. Απλά η επόμενη έκδοση της συσκευής επέβαλε να ξαναγραφτούν σχεδόν τα πάντα. Ο παλιός κώδικας ήταν ουσιαστικά άχρηστος ή ασύμφορος μετά από 1-2 χρόνια το πολύ. Φαντάζεσαι να ίσχυαν τα ίδια για την Oracle; Ο Larry Έλισον θα είχε γίνει ζητιάνος.


Back... για κάποιες μέρες δεν δούλευε ο μετατροπέας...

αν όντως πιστεύεις ότι ο κώδικας για pc είναι περισσότερος από το κώδικα για embedded... τότε ρίξε μια ματια τριγύρω σου και μετρα τις συσκευές... άμα "δισκολεντις" να πιστης πες μου να σου πω μερικές από τις δεκάδες συσκευές που "χρισομπιις"...

όσο για τον κώδικα... τίποτα δεν χρειάζεται να ξαναγραφτεί άμα δεν τον γράψεις σε assembly... όσος κώδικας υπάρχει σε C χρησιμοποιείτε μια χαρά... όσο για τις μπαταρίες που λες για "ξανασκεψουτο"... άμα μια συσκευή ξυπνάει κάθε 10 λεπτά, κάνει μια μέτρηση την επεξεργάζεται και τι στέλνει και ξανακοιμάται για 10 λεπτά... τότε η ρουτίνα που θα τρέξει δεν επηρεάζει τι ζωή τις μπαταρίας? το ίδιο είναι να τρέξει μισό δευτερόλεπτο και το ίδιο είναι να τρέξει 5 δευτερόλεπτα? ;)

DarthMoul
07-08-2005, 11:43
Το ζήτημα δεν είναι πόσες συσκευές χρησιμοποιώ. Αλλάζεις την κατεύθυνση της συζήτησης σκοπίμως. Το ζήτημα είναι πόσοι γράφουν software για αυτές τις συσκευές και αν τελικά παράγουν περισσότερο κώδικα από τους υπόλοιπους. Αυτό μπορείς να το απαντήσεις τεκμηριωμένα;

Φυσικά θα γράψεις και assemby σε τέτοιες συσκευές. Μόνος σου είπες τον λόγο. Θα εξοικονομήσεις και τον τελευταίο κύκλο μηχανής. Βέβαια η assembly κοστίζει, οπότε είναι θέμα τι ποιότητας και τιμής προϊόν θέλεις να κατασκευάσεις. Εξαρτάται και τι background έχει ο κατασκευαστής. Αν έχει background κινέζου μπακάλη αυτά δεν τον ενδιαφέρουν.

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

sleeper
07-08-2005, 14:20
πόσοι γραφουν κώδικα για embedded.... παρα πολύ... ας ξεκινήσουμε με τους βασικούς...
ηλεκτρονική, ηλεκτρολόγοι, "κοντρολαδες", μηχανολόγοι, embedded software eng., κανονικοί μηχανικοί λογισμικού...

και σε ποιο ακραίες περίπτωσις ξέρω φυσικούς, μαθηματικούς και χημικούς που γραφουν λογισμικό για embedded...

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

άλλες εταιρίες που κάνουν IP για embedded συσκευές γραφουν κώδικα...

θα σου φέρω ένα απλό παράδειγμα στο πάρκο που είναι το ινστιτούτο που κάνω το master, η Motorola έχει γραφεία που γραφουν κώδικα για embedded... η Cadance το ίδιο δεν νομίζω να είναι κάποια από αυτές τις 2 γνωστη για τους προγραμματιστές τις... η Motorola κάνει συσκευές τηλεπικοινωνιών περισσότερο και η Cadance είναι ποιο γνωστη για το προγράμματα σχεδίασης ηλεκτρονικών... και όμως και οι 2 κάνουν embedded...

DarthMoul
07-08-2005, 16:28
Στοιχεία έχεις; Αριθμούς; Στατιστικά; Αυτό σου ζητάω. Η αίσθηση σου δεν είναι στοιχείο. Αν αντιστοιχίσεις την embedded εφαρμογή της καφετιέρας με μια άλλη που δεν είναι embedded και ονομάζεται Oracle, και από αυτό κρίνεις ότι η παραγωγή κώδικα για embedded είναι μεγαλύτερη από ότι για όλα τα άλλα εγώ σηκώνω τα χέρια ψηλά. Φυσικά και γράφουν πολλοί για embedded. Αλλά τελικά η παραγώγη αυτού του κώδικα είναι απειροελάχιστη σε σχέση με το σύνολο. Αλλιώς θα έπρεπε να έχουμε software houses μεγαθύρια που να παράγουν κώδικα για embedded και όχι το αντίστροφο που συμβαίνει σήμερα. Επιμένεις ακόμα ότι το 90% του κώδικα που παράγεται είναι για embedded;

Μπορεί να γράφει η motorola λίγο πιο κάτω από το σπίτι σου, αλλά λίγο πιο κάτω από το δίκο μου γράφει κάποιος άλλος για pc. So what? One case is no case. Με μεμονομένα παραδείγματα δεν θεμελιώνονται ισχυρισμοί.

sleeper
10-08-2005, 13:32
Στοιχεία έχεις; Αριθμούς; Στατιστικά; Αυτό σου ζητάω. Η αίσθηση σου δεν είναι στοιχείο. Αν αντιστοιχίσεις την embedded εφαρμογή της καφετιέρας με μια άλλη που δεν είναι embedded και ονομάζεται Oracle, και από αυτό κρίνεις ότι η παραγωγή κώδικα για embedded είναι μεγαλύτερη από ότι για όλα τα άλλα εγώ σηκώνω τα χέρια ψηλά. Φυσικά και γράφουν πολλοί για embedded. Αλλά τελικά η παραγώγη αυτού του κώδικα είναι απειροελάχιστη σε σχέση με το σύνολο. Αλλιώς θα έπρεπε να έχουμε software houses μεγαθύρια που να παράγουν κώδικα για embedded και όχι το αντίστροφο που συμβαίνει σήμερα. Επιμένεις ακόμα ότι το 90 του κώδικα που παράγεται είναι για embedded;

Μπορεί να γράφει η motorola λίγο πιο κάτω από το σπίτι σου, αλλά λίγο πιο κάτω από το δίκο μου γράφει κάποιος άλλος για pc. So what? One case is no case. Με μεμονομένα παραδείγματα δεν θεμελιώνονται ισχυρισμοί.

it is 2 cases... there is Cadence ας well :044:

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

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

και δεν μίλησα για κώδικα που υπάρχει ήδη αλλα για κώδικα που γράφετε ;)

DarthMoul
12-08-2005, 00:02
Πάντως οι τζίρος που έκανε το 2003 η αγορά του embedded software ήταν κάτι λιγότερο από το 1% του συνόλου. Θα σου έρθουν και τα links μόλις επιστρέψω από τις διακοπές γιατί τώρα είμαι σε cafe. Αν το 90% της παραγωγής είναι για embedded, άρα έχουμε περίπου και το 90% του κόστους για embedded. Το 1% του τζίρου δεν δικαιολογεί σε καμμία περίπτωση αυτό που λες. Οι αναλογίες κόστους/τζίρου θα είναι περίπου οι ίδιες. Εκτός και αν έχεις κάποιο στοιχείο να το ανατρέπει. Στοιχείο σου ζητάω από την αρχή της συζήτησης και ακόμα περιμένω. Αν δεν το έχεις απλά πες το μας. Δεν είναι κακό. Και η γνώμες είναι σεβαστές. Αλλά δεν είναι στοιχεία.

YiannisM
23-12-2005, 21:05
Άρα λοιπόν το θέμα κατέληξε στις τεχνικές βελτιστοποίησης κώδικα, ενώ στην αρχή είχα νομίσει ότι ήταν γενικότερο κι ότι αναφερόταν περισσότερο στην επίτευξη κι αξιοποίηση μεγάλης υπολογιστικής ισχύος για την επίλυση πολύπλοκων και σύνθετων προβλημάτων.


Θα προστέσω κάτι όσον αφορά περισσότερο το δεύτερο θέμα.

Όσο πιο πολύπλοκο είναι ένα πρόβλημα για τη λύση του οποίου κατασκευάζεται κάποιο πρόγραμμα (ή όσο μεγαλύτερη είναι μια εφαρμογή), τόσο και η ανάγκη βελτιστοποίησης δεν αρκεί να επιχειρείτε μόνο στον κώδικα αλλά και στις υπόλοιπες φάσεις υλοποίησης του έργου, όπως είναι η ανάλυση και η σχεδίαση (analysis + design) του σχετικού συστήματος που θέλουμε να κατασκευάσουμε.
Οι 3 φάσεις υλοποίησης ενός project είναι αυτές: Ανάλυση, Σχεδίαση, Υλοποίηση (Coding), χωρίς βέβαια να υπολογίζουμε τη συλλογή requirements+specifications, το testing και το packaging. Αν και σε μικρά projects συνηθίζεται η Ανάλυση και η Σχεδίαση να πραγματοποιούνται σχεδόν από τον ίδιο άνθρωπο που υλοποιεί και τον κώδικα (τον προγραμματιστή), κι έτσι δεν υπολογίζονται και πάρα πολύ, εν τούτοις έχουν νόημα ακόμη κι εκεί.

Σε μεγάλα projects όμως, το πρόβλημα προς επίλυση αντιμετωπίζεται σε διάφορα επίπεδα ώς προς τη γενικότητα με την οποία "το κοιτάμε" κάθε φορά, κατά τη φάση της ανάλυσης! Και εκεί χωράει βελτιστοποίηση!
Το ίδιο και στη σχεδίαση, όπως φυσικά και στην υλοποίηση (coding).

backgroundman
24-12-2005, 13:53
Καλησπέρα,
1. Όσον αφορά το embedded software συμφωνώ οτι είναι πράγματι αρκετό αλλα δε μπορώ να πιστέψω οτι είναι περισσότερο απο το λογισμικό που φτιάχνεται για pc/mac. Να πω επίσης οτι αρκετές συσκευές δεν χρησιμοποιούν embedded λογισμικό αλλα FPGAs ή στη καλύτερη περίπτωση (και πολύ σπάνια) ASIC chips.

2. Όσον αφορά τους φυσικούς/μαθηματικούς/χημικούς που γράφουν embedded εφαρμογές είναι πολύ λίγοι. Αυτό στο λέει ένας φυσικός που εχει γράψει embedded λογισμικό για DSP κάρτες της ΤΙ. Συνήθως οι φυσικοί/μαθηματικοί/χημικοί δεν ασχολούνται με embedded γιατι είναι σχετικά πιο δύσκολο απο ενα απλό λογισμικό στο pc. Επίσης αυτό που χρειάζονται συνήθως είναι είτε μοντελοποίηση είτε προσωμοίωση κάποιων φαινομένων και υπάρχουν αρκετά προγράμματα που μπορούν να το κάνουν απλά και σχετικά εύκολα. Στη καλύτερη περίπτωση θα γράψουν δικιά τους εφαρμογή σε C και δε θα στραφούν σε embedded λογισμικό.

3. @YiannisM : Συμφωνώ μαζί σου. Όσο για το τελευταίο που είπες, αυτό που προσπαθείς να βελτιστωποιήσεις στην ανάλυση είναι ο αλγόριθμος που θα σου λύνει το πρόβλημα που αντιμετωπίζεις. Είναι ίσως η σημαντικότερη βελτιστοποίηση που μπορείς να κάνεις, για αυτό και στο εξωτερικό το μεγαλύτερο μέρος του χρόνου καταλαμβάνει η ανάλυση και η σχεδίαση της λύσης που προτείνεις για κάποιο πρόβλημα. Αν η ανάλυση και η σχεδίαση έχει γίνει σωστά και βελτιστοποιημένα τότε είναι σχετικά πιο εύκολο να το υλοποιήσεις. Αν έχεις κάνει λάθος στην ανάλυση/σχεδίαση ή δεν έχεις χρησιμοποιήσει βελτιστοποιημένους αλγόριθμους τότε όσο βελτιστοποιημένο κώδικα και να γράψεις δε θα μπορέσεις να κάνεις και πολλά.