Προς το περιεχόμενο

C quiz ;p


afnman

Προτεινόμενες αναρτήσεις

Καλησπερα...

Εστω code σε C για console ενος μονοεπεξεργαστη ;p

Α->

>
int i;
for(i=0;i<40;i++)
{
if(i==10) do_this();
else if(i==20) do_that();
else something();
}

 

B->

>
int i;
for(i=0;i<10;i++)
{

something();
}
do_this();
for(i=11;i<20;i++)
{
something();
}
do_that();
for(i=21;i<40;i++)
{
something();
}

Aν μεταγλωττιστουν με εναν Microsoft compiler ,ποιος κωδικα θεωρειτε καλύτερο ή ειναι το ίδιο; Eγω λεω το Β λογω ταχυτητας αλλα δεν ειμαι σιγουρος 100%

Eξηγειστε γιατι. :P

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Φίλε μου, ο πρώτος κωδικας και ο δευτερος δεν κανουν το ιδιο πραγμα.

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

 

o δευτερος θα εκτελεσει 10 φορες to something() meta θα βγει θα εκτελέσει το do_this();

kai μετα θα εκτελέσει αλλεσ 9 φορες το something () meta to do?that(); kai telos 19 φορες something():

 

ΔΕν μπορεις να συγκρινεις δυο διαφορετικουσ κωδικες

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Φυσικα ο κωδικας που θα φτιαξει ο compiler θα ειναι διαφορετικος αλλα τα αποτελεσματα ειναι παντα 100% τα ιδια.

 

Ουσιαστικα στο Β εχεις απαλειψει αποφασεις που θα μπορουσε να παρει ο υπολογιστης. Χωρις να γνωριζω και πολλα απο τεχνολογια compilers διαισθητικα θα ελεγα οτι το Β θα ειναι θεωρητικα πιο γρηγορο.

 

Πρακτικα, ο χρονος εκτελεσης των something(), do_this() kai do_that() παιζει τον πιο σημαντικο ρολο. Δεν νομιζω οτι μπορεις να εχεις μετρησιμα αποτελεσματα σε αποδοση χωρις να αλλαξεις τον κωδικα σε αυτα

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Πρακτικα, ο χρονος εκτελεσης των something(), do_this() kai do_that() παιζει τον πιο σημαντικο ρολο. Δεν νομιζω οτι μπορεις να εχεις μετρησιμα αποτελεσματα σε αποδοση χωρις να αλλαξεις τον κωδικα σε αυτα

 

Aντικατεστησε τα something(),do_this() και do_that() με cout << "something",cout << "do_this",cout << "do_that" αντιστοιχα

 

Φίλε μου, ο πρώτος κωδικας και ο δευτερος δεν κανουν το ιδιο πραγμα.

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

 

o δευτερος θα εκτελεσει 10 φορες to something() meta θα βγει θα εκτελέσει το do_this();

kai μετα θα εκτελέσει αλλεσ 9 φορες το something () meta to do?that(); kai telos 19 φορες something():

 

ΔΕν μπορεις να συγκρινεις δυο διαφορετικουσ κωδικες

στον Α:

απο 0 εως και 9 ( συνολο 10 φορες) εκτελειτε tο something()

στην 10η φορα εκτελειτε το do_this()

απο την 11η φορα μεχρι και την 19η φορα εκτελειτε το something() (σύνολο 9 φορες)

την 20 φορά εκτελείται do_that

απο την 21 εως και την 39 φορά εκτελειτε το something()

(συνολο 19 φορές)

..its the same shit...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Από ότι είδα στα γρήγορα, στην CodeGear Turbo C++ Explorer (δεν έχω πρόχειρη την MS-Visual C++) - φαίνεται πως ισοφαρίζουν, στο δικό μου υπολογιστή (Core Duo 1.60GHz).

 

Για το τεστ ζητώ από τον compiler, fastest possible code και Pentium Pro instruction set.

 

Επίσης έχω προσθέσει μια μικρή χρονο-καθυστέρηση σταθερή για κάθε ρουτίνα.

 

>
//---------------------------------------------------------------------------

#include <time.h>
#include <iostream>
#pragma hdrstop

#define	_DELAY	500

//---------------------------------------------------------------------------
void	do_this(void);
void	do_that(void);
void	something(void);
void	delay(int);

#pragma argsused
int main(int argc, char* argv[])
{
clock_t	ctBeginA,
		ctEndA,
		ctBeginB,
		ctEndB;
int i;			

ctBeginA = clock();
	for(i=0;i<40;i++)
	 {
		if(i==10) do_this();
			else if(i==20) do_that();
				else something();
	 }		
ctEndA = clock();

ctBeginB = clock();
	for(i=0;i<10;i++)
		something();
	do_this();
	for(i=11;i<20;i++)
		something();			
	do_that();
	for(i=21;i<40;i++)		
		something();
ctEndB = clock();

std::cout<<std::endl<<std::endl<<"A = "<<ctEndA-ctBeginA<<std::endl<<"B = "
		 <<ctEndB-ctBeginB<<std::endl<<std::endl<<"Press Enter to exit..";
std::cin.get();
return 0;
}
//---------------------------------------------------------------------------
void	do_this(void)
{
std::cout<<"do this";	
delay(_DELAY);
}
void	do_that(void)
{
std::cout<<"do that";
delay(_DELAY);	
}
void	something(void)
{
std::cout<<"something";
delay(_DELAY);	
}
void	delay(int nDelay)
{
clock_t	ctBegin = clock(),
		ctEnd;
do{
	ctEnd = clock();
	}while((ctEnd-ctBegin)<=nDelay);
}

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Eτρεξα το prog sou σε Visual studio.NET xωρις κανενα optimization και Intel duo core 1.66

A= 20656

B= 20625

 

Μια ερώτηση...η time είναι ξεχωριστο thread του προγράμματος και διακοπτεται κανονικά απο άλλες διεργασιες σωστά;Εννοω οτι μετραει μονο αυτο το προγραμμα και οχι τυχον άλλες διακοπες.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Υπό φυσιολογικές συνθήκες η delay οφείλει να διακόπτει το do{ }while() loop όταν συμπληρωθεί ο απαραίτητος χρόνος, αν υπάρχει δραστηριότητα της CPU, όπως συμβαίνει πάντα σε ένα multi-task περιβάλλον, μπορεί να υπάρξουν καθυστερήσεις στην ολοκλήρωση της (έστω και ελάχιστες -της τάξεως των msec), για αυτό και ο έλεγχος δεν είναι απόλυτος !=nDelay αλλά σχετικός <=nDelay.

 

Υπό αυτό το πρίσμα, η διαφορά που μου δίνεις δεν είναι σημαντική καθώς μπορεί να καταγράφει περιπτώσεις που η CPU απασχολείται με κάτι άλλο (κλείσε όλες τις εφαρμογές σου + συμβουλέψου τον Task Manager).

 

Για να δεις καλύτερα πόσο ασήμαντη είναι η διαφορά σε δευτερόλεπτα, άλλαξε τα ctEndA-ctBeginA και ctEndB-ctBeginB σε (ctEndA-ctBeginA)/CLK_TCK και (ctEndB-ctBeginB)/CLK_TCK αντίστοιχα -οπότε θα έχεις μια διαφορά των 31 msec καθώς και οι δυο ρουτίνες ολοκληρώνονται στα 20'', δηλαδή διαφορά .. αδιάφορη! (20",656 - 20",625 = 0,031) ;)

 

Υ.Γ.

Το CLK_TCK = 1000 σε CodeGear/Borland compilers.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

> Aν μεταγλωττιστουν με εναν Microsoft compiler

 

Αυτό τώρα τι υποτίθεται ότι είναι, απαξιωτικό για τη Microsoft? Μακάρι και ο gcc να είχε το ίδιο καλό optimization...

 

Καλά βρε ποιος βάζει τέτοιες ασκήσεις;

 

Όπως ήταν αναμενόμενο και όπως έδειξαν οι δοκιμές, 2 παραπάνω if στο εσωτερικό ενός βρόχου είναι αμελητέα για σύγχρονες αρχιτεκτονικές, επειδή κάνουν πολύ καλές προβλέψεις για τα jump που έρχονται. Εξάλλου ο κώδικας είναι πολύ μικρός και πιθανώς να μην δημιουργούνται καν cache misses, όπως θα δημιουργούνταν σε ένα "κανονικό" πρόγραμμα - το οποίο και θα έβγαζε άχρηστες οποιεσδήποτε μετρήσεις (ένα cache miss κοστίζει πολύ περισσότερο από μερικές if).

 

Η ερώτηση νομίζω ότι πρέπει να απαντηθεί θεωρητικά, όχι πρακτικά. Π.χ. αν τρέξουμε τον παραπάνω κώδικα με Microsoft compiler σε επεξεργαστή 8086 είμαι σίγουρος ότι η διαφορά στην ταχύτητα εκτέλεσης θα είναι εμφανής. Το λέω με σιγουριά γιατί δεν πρόκειται κανείς να βρει 8086 για να με βγάλει λάθος! ;) Καλά πλάκα κάνω, απλά έχω φάει αμέτρητα χρόνια σε assembly optimization σε 8086 γι' αυτό το λέω.

 

Θεωρητικά, εφόσον στην Α περίπτωση έχεις 2 παραπανίσια if, το A είναι πιο αργό.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Και για την απολυτη ταχυτητα

 

>

something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
do_this();
something();
something();
something();
something();
something();
something();
something();
something();
something();
do_that();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();
something();

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Believe it or not στους καινούργιους επεξεργαστές αυτό είναι πιο αργό λόγω cache & pipelining... :)

 

Όποιος έχει όρεξη να δει υπερ-optimized κώδικα Delphi & Assembly ας φέρει μια βόλτα στο http://fastcode.sourceforge.net/

Μιλάμε για χιλιάδες φορές μεγαλύτερη ταχύτητα από τις αντίστοιχες συναρτήσεις της VCL..

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Από όσο γνωρίζω (και βλέπω κατά το debugging εφαρμογών), τμήματα του fast-code project (pure asm) χρησιμοποιούνται στις νεότερες εκδόσεις της VCL από την CodeGear.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Believe it or not στους καινούργιους επεξεργαστές αυτό είναι πιο αργό λόγω cache & pipelining... :)

..

 

Γιατι ποιο αργό;.. cache και pipelining είναι νομιζω τεχνικές

για πιο γρηγορη αναφορά στην μνήμη και εκτέλεση του κώδικα αντίστοιχα.Δεν καταλαβαίνω γιατι να ειναι πιο αργο....:rolleyes:

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Με εντελώς στο περίπου νούμερα, απλά για το σκεπτικό:

1) Έστω ότι η cache χωράει 100 byte.

2) Η έκδοση με το loop είναι μικρότερη. Έστω ότι είναι 40 byte.

3) Η έκδοση χωρίς loop είναι μεγαλύτερη. Έστω ότι είναι 80 byte.

4) Έστω ότι η ίδια η something() είναι 50 byte.

 

> Στην πρώτη έκδοση βγαίνει 40 + 50 = 90 που είναι μικρότερο από 100, άρα χωράει όλη στην cache, ενώ η δεύτερη έκδοση 80 + 50 = 130 > 100 και προκαλούνται cache misses. Ένα cache miss κοστίζει πολύ, περισσότερο από το if/jmp ενός loop που υπάρχει ήδη στην cache.

 

Ξαναλέω ότι τα νούμερα δεν έχουν καμία σχέση με την πραγματικότητα, το σκεπτικό έγραψα.

 

Γενικά δηλαδή οι μικροί κώδικες, ακόμα κι αν έχουν cmp/jmp, μπορεί να είναι πιο γρήγοροι είτε λόγω cache, είτε λόγω cache-line, είτε λόγω paging κτλ.

 

Google για cache optimizations και θα βρεις μπόλικα papers.

 

@DirectX: άστα, μας έχει σπάσει τα νεύρα η VCL. Όντως μετά από ένα σωρό reports στο Quality Central συμπερίλαβε στις πρόσφατες εκδόσεις της κώδικα από τη fastcode, αλλά ακόμα συνεχίζει και συμπεριλαμβάνει δικές της assembly functions που είναι υλοποιημένες λάθος (όχι αργές, λάθος)!

Π.χ. ένα που έκλεισε πρόσφατα: http://qc.borland.com/wc/qcmain.aspx?d=22454

 

Για την ταχύτητα, δες π.χ. εδώ

http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_21982965.html

έναν διαγωνισμό που είχαμε κάνει για την ταχύτερη StringReplace. Παράδειγμα αποτελέσματος:

 

On my PC it had the following results on 1 Mb text:

Delphi StringReplace ~= 300 sec

Alkisg_StringReplace < 1 sec.

 

Για μεγαλύτερο string του Delphi χρειάζεται μέρες και δεν είχαμε την υπομονή να την περιμένουμε...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...