He encontrado un comportamiento extraño de std :: set.std :: establecido rápido y lento, ¿qué está pasando?
Aquí está el código:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
#include <vector>
#include <set>
using namespace std;
int main(int argc, char *argv[])
{
set<int> b[100];
for (int o=0; o<10; o++)
{
int tt = GetTickCount();
for (int i=0; i<5000000; i++)
{
b[o].insert(i);
}
tt = GetTickCount() - tt;
b[o].clear();
printf("%d\n", tt);
}
return 0;
}
estoy corriendo en Windows XP.
Aquí está la parte interesante: este primer tiempo impreso es de aproximadamente 3500 ms, ¡mientras que todos los siguientes son más de 9000 ms! ¿Por qué está sucediendo eso?
Ah, y esto solo ocurre en la versión de lanzamiento (optimización de -O2).
No ocurre en Linux (después de cambiar el código para compilar allí).
Una cosa más: cuando lo ejecuto durante el perfilado con Intel VTune, siempre lleva unos 3000 ms, así es como debería ser.
ACTUALIZACIÓN: Aquí hay un código nuevo:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
const int count = 10000000;
int **a = new int*[count];
for (int o=0; o<10; o++)
{
int ttt = GetTickCount();
for (int i=0; i<count; i++)
{
a[i] = new int;
*a[i] = i;
}
int ttt2 = GetTickCount();
for (int i=0; i<count; i++)
{
int r1 = rand() * 10000 + rand();
int r2 = rand() * 10000 + rand();
r1 = r1%count;
r2 = r2%count;
int *e = a[r1];
a[r1] = a[r2];
a[r2] = e;
}
int ttt3 = GetTickCount();
for (int i=0; i<count; i++)
{
delete a[i];
}
int ttt4 = GetTickCount();
printf("%d %d\n", ttt2-ttt, ttt4-ttt3);
}
return 0;
}
Este es el mismo problema. Lo que sucede es que asigno muchos objetos pequeños y luego los elimino en orden aleatorio, por lo que es similar a como se ve en std :: set. Este es un problema de administración de memoria de Windows. Realmente no puede manejar bien muchos pequeños allocs y elimina.
Esto probablemente esté relacionado con algunos detalles de implementación de su biblioteca/plataforma estándar.Podría tratar de ejecutarlo en un generador de perfiles y verificar dónde se está gastando el tiempo. Puede haber muchas cosas pasando, desde las diferencias en el esquema de asignación de los pases iniciales y consecutivos (que lanzó la memoria) a casi cualquier otra cosa. También tenga en cuenta que debe usar -O3 para el rendimiento. –
Quizás esté relacionado con la programación del hilo del sistema. Su hilo no es el único que necesita tiempo de procesador. Puede usar 'GetThreadTimes' para ver cuánto tiempo de procesador realmente consumió su hilo – valdo
Su mejor opción podría ser mirar el código ensamblado generado con' -O2' para ver si hay algo allí que pueda explicar este comportamiento. – NPE