| size = 65536 |
procedura inline |
Non Inline |
for(i=0;i<size;i++) |
41us |
131us |
do {
|
48us |
50us |
for(i=0;i<size;i++) |
62us |
146us |
| size= |
1 byte |
1024 bytes |
65536 bytes |
memset(dst, x, size); |
0.02us |
0.21us |
7.2us |
for(i=0;i<size;i++) |
<0.002us | 0.66us |
42us |
for(j=len;j;j--) |
<0.002us | 0.66us |
42us |
for(j=len;j;j--) |
<0.002us | 0.75us |
49us |
do {
|
<0.002us | 0.75us |
48us |
label:
MOV [EDX], CL
INV EDX
DEC ECX ; puo' essere accoppiato in sistemi a piu' pipeline
JNZ label ; la branch predition salta il confronto
| size= |
1 byte |
1024 bytes |
65536 bytes |
memcpy(dst, src, size); |
0.02us |
0.28us | 14us |
for(i=0;i<size;i++) |
<0.002us |
1.09us |
69us |
do {
|
<0.002us |
1.11us |
73us |
| size=65536 |
macchina generica |
pentium4 |
for(i=0;i<size;i++) |
69us |
104us |
i = size; |
72us |
58us |
for(i=0;i<size;i++) |
41us |
43us |
do {
|
48us |
39us |
Le STL allocano, in maniera trasparente all'utente, sia il puntatore alla memoria del testo contenuto nella stringa, anche un valore che indica quanto la stringa risulta lunga. Questo dato aggiuntivo permette di risparmiare tempo prezioso quando si eseguono operazioni intensive su stringhe.
La stessa cosa si puo' fare infatti creando una classe C++ che memorizza sia la lunghezza della stringa che il suo contenuto, per esempioclass bstring {
unsigned int len;
const char *str;
public:
...
};
Una struttura come bstring ha
le medesime prestazioni, se non migliori, delle std::string.| 10 bytes |
100 bytes |
1000 bytes |
|
unsigned int len = strlen(buffer) + 1; char *target = new char [len]; memcpy(target, buffer, len); |
0.16us |
0.26us | 0.74us |
std::string s(buffer); |
0.15us |
0.21us | 0.78us |
| 10 bytes |
100 bytes |
1000 bytes |
|
| strlen( ) |
0.009us |
0.053us | 0.378us |
s.size() |
<0.001us |
<0.001us | <0.001us |
Il comando size delle
stringhe restituisce la lunghezza della stringa, memorizzata
all'interno della struttura. Nessun accesso alla memoria viene fatto,
se non quello del dato di lunghezza stesso.
| 10 bytes |
100 bytes |
1000 bytes |
|
| Approccio C |
0.20us |
0.33us |
1.01us |
Approccio C++ con bstring |
0.20us |
0.27us | 0.59us |
Approccio C++ con STL |
0.35us | 0.47us | 0.85us |
| time |
|
| { unsigned char *v = new unsigned char [size]; v[0]=0; delete [] v; } |
0.14us |
{
|
6.2us |
| size= |
16384 bytes |
for(i=0;i<size;i++) |
34us |
for(vector<unsigned char>::iterator i=stlmem.begin();i!=stlmem.end();i++) |
42us |
vector<unsigned char>::iterator end = stlmem.end(); |
43us |
for(i=0;i<size;i++) |
36us |
| gcc-3.3 |
gcc-3.4 |
||
| Codice MMX inline |
void ll_sse_diff_line(unsigned |
0.18ms |
0.18ms |
Codice scritto in maniera tale da usare le 2 pipeline. |
void ll_diff_line(unsigned char *d, const unsigned char *a, const unsigned char *b, unsigned int size) |
0.61ms Se invece di 2, si usano 8 copie c'e' un peggioramento. |
0.61ms Se invece di 2, si usano 8 copie stavolta non cambiano le prestazioni. |
Codice Normale |
void ll_diff_line(unsigned char *d, const unsigned char *a, const unsigned char *b, unsigned int size) |
1.6ms (1.2ms non usando
march=pentium4) |
0.67ms |
| Codice Normale con il For |
void ll_diff_line_for(unsigned char *d, const unsigned char *a, const unsigned char *b, unsigned int size) |
0.63ms |
0.76ms |
T subabs(T a, T b)
{
return (a>b) ? (a-b) : (b-a);
}
Il gcc-4.0.0 non e' riuscito a vettorizzare nessuno dei loop.
| Descrizione |
Codice |
gcc-3.4.4 |
gcc-4.0.0 |
|
| SIZE=256*256*16 |
int a[SIZE], b[SIZE], c[SIZE]; |
5.0ms |
4.3ms |
|
|
5.0ms |
1.5ms |