Debes hacer un perfil también para ver dónde está el cuello de botella.
Quizás esté en el kernel, tal vez esté al límite de su hardware. Hasta que lo perfile para descubrir que está tropezando en la oscuridad.
EDIT:
Ok, una respuesta más a fondo este tiempo, entonces. De acuerdo con la documentación de Boost.Iostreams basic_file_source
es solo un contenedor alrededor de std::filebuf
, que a su vez se basa en std::streambuf
. Para citar la documentación:
CopyConstruible y Contenedor asignable para std :: basic_filebuf abierto en modo de solo lectura.
streambuf
proporciona un método pubsetbuf (no la mejor referencia tal vez, pero el primer Google se volvió hacia arriba) que se puede, al parecer, utilizar para controlar el tamaño del búfer.
Por ejemplo:
#include <fstream>
int main()
{
char buf[4096];
std::ifstream f;
f.rdbuf()->pubsetbuf(buf, 4096);
f.open("/tmp/large_file", std::ios::binary);
while(!f.eof())
{
char rbuf[1024];
f.read(rbuf, 1024);
}
return 0;
}
En mis pruebas (optimizaciones de descanso, sin embargo) De hecho, me puso peor rendimiento con un buffer de 4096 bytes de un buffer de 16 bytes, pero tu caso es distinto - un buen ejemplo de por qué usted debería siempre perfil primero :)
Pero, como dices, el basic_file_sink
no proporciona ningún medio para acceder a esto ya que oculta el filebuf
subyacente en su private part.
Si usted piensa que esto es un error que podía:
- instan a los desarrolladores de Boost para exponer dicha funcionalidad, utilice la lista de correo o el trac.
- Cree su propia envoltura
filebuf
que expone el tamaño del búfer. Hay un section en el tutorial que explica cómo escribir fuentes personalizadas que pueden ser un buen punto de partida.
- Escriba una fuente personalizada basada en lo que sea, que hace todo el almacenamiento en caché que desee.
Recuerde que su disco duro y el kernel ya almacenan en caché y almacenan en búfer las lecturas de archivos, lo que no creo que aumente mucho el rendimiento del almacenamiento en caché aún más.
Y para terminar, una palabra sobre la creación de perfiles. Hay un montón de potentes herramientas de creación de perfiles disponibles para Linux y ni siquiera conozco la mitad de ellas por su nombre, pero por ejemplo está iotop, que es bastante ordenado porque es muy fácil de usar. Es bastante parecido a la parte superior, pero en su lugar muestra métricas relacionadas con el disco. Por ejemplo:
Total DISK READ: 31.23 M/s | Total DISK WRITE: 109.36 K/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
19502 be/4 staffan 31.23 M/s 0.00 B/s 0.00 % 91.93 % ./apa
me dice que mi progam gasta más del 90% de su tiempo de espera para IO, es decir, es obligado IO. Si necesitas algo más poderoso, estoy seguro de que Google puede ayudarte.
Y recuerde que la evaluación comparativa de un caché frío o caliente afecta en gran medida el resultado.
Tal vez esta es una pregunta para otra publicación, pero ¿cómo podría perfilarlo? Sé cómo usar gprof, pero solo me dice sobre el tiempo de CPU, y aquí estoy bastante seguro de que el cuello de botella es E/S de disco. O si alguien puede decirme cómo configurar correctamente el tamaño del búfer, solo puedo probarlo y ver si me ayuda. – user387250
@jwfoley: Me gusta [Valgrind] (http://valgrind.org/) callgrind profiler. En lo que respecta a mi experiencia (lea como: no puedo garantizar nada), también informa el tiempo pasado en las llamadas al kernel, algo que nunca podría hacer gprof. Lo uso para perfilar una aplicación con OpenGL, por ejemplo, e informa correctamente el tiempo pasado en el código del controlador de video. Es muy fácil de usar (valgrind --tool = callgrind ./your-app). Utilice [KCachegrind] (http://kcachegrind.sourceforge.net/html/Home.html) para interpretar los resultados. El único inconveniente es que su aplicación se ejecutará 20 veces más o menos durante el perfilado. – Staffan
@Staffan: Bien, probé callgrind + KCachegrind y estoy impresionado con el generador de perfiles, pero todavía no sé lo que estoy buscando. Los resultados son bastante similares a los de gprof. Algo llamado T.3577 tiene un alto "Incl." pero bajo "Yo"; la mayor parte de su tiempo parece gastarse en std :: basic_ios. Tal vez esa es la E/S de disco? Todavía me gustaría una respuesta a mi pregunta original de cómo configurar el tamaño del búfer. Si es fácil, entonces puedo probarlo y ver si me ayuda, pero sería útil saber de todos modos. – user387250