¿Cuál sería un tamaño de búfer ideal? [duplicar]

Posible duplicado:
¿Cómo se determina el tamaño de búfer ideal cuando se usa FileInputStream?

Al leer datos sin procesar de un archivo (o cualquier flujo de entrada) usando C++ istream familia read() o C's fread(), se debe proporcionar un búfer y una cantidad de datos para leer. La mayoría de los programas que he visto parecen elegir arbitrariamente una potencia de 2 entre 512 y 4096.

  1. ¿Hay alguna razón por la que tiene que/debería ser una potencia de 2, o es solo la inclinación natural del programador a las potencias de 2?
  2. ¿Cuál sería el número "ideal"? Por "ideal" quiero decir que sería el más rápido. Supongo que tendría que ser un múltiplo del tamaño del búfer del dispositivo subyacente. ¿O tal vez del búfer del objeto de flujo subyacente? ¿Cómo determinaría cuál es el tamaño de esos búferes, de todos modos? Y una vez que lo haga, ¿el uso de un múltiplo aumentaría la velocidad con respecto al uso del tamaño exacto?

EDITAR
La mayoría de las respuestas parecen ser que no se puede determinar en tiempo de compilación. Estoy bien con encontrarlo en tiempo de ejecución.

preguntado el 22 de mayo de 12 a las 09:05

Creo que el tamaño del búfer depende del compilador o de la máquina (lo siento, no sé cuál o tal vez son ambos). La única forma de saberlo es intentar leer varios tamaños de datos. Debe ser rápido, así que hazlo 100 veces y saca el promedio. Eso no debe ser una línea recta. Supongo que debería notar cuando haya cruzado el punto donde se debe leer otro búfer de datos. (Alternativamente, puede buscar en el código fuente de C/C++...) -

En caso de duda, siempre haga que el tamaño de sus búferes sea una potencia de dos. Otros programadores pensarán que lo hiciste por alguna razón inteligente. ;-)-

Re editar: el tiempo de ejecución no ayuda mucho. Necesita crear perfiles en el momento del desarrollo, a menos que pueda permitirse "ejecuciones de calentamiento" extremas con una gran cantidad de datos cada vez que se inicia su código de búfer adaptativo. -

6 Respuestas

FUENTE:
¿Cómo se determina el tamaño de búfer ideal cuando se usa FileInputStream?

El tamaño óptimo del búfer está relacionado con varias cosas: el tamaño del bloque del sistema de archivos, el tamaño de la memoria caché de la CPU y la latencia de la memoria caché.

La mayoría de los sistemas de archivos están configurados para usar tamaños de bloque de 4096 u 8192. En teoría, si configura el tamaño de su búfer para leer unos pocos bytes más que el bloque del disco, las operaciones con el sistema de archivos pueden ser extremadamente ineficientes (es decir, si configuró su búfer para leer 4100 bytes a la vez, cada lectura requeriría 2 lecturas de bloque por parte del sistema de archivos). Si los bloques ya están en la memoria caché, terminará pagando el precio de RAM -> latencia de memoria caché L3/L2. Si no tiene suerte y los bloques aún no están en la memoria caché, también paga el precio de la latencia del disco -> RAM.

Esta es la razón por la que ve la mayoría de los búferes con un tamaño de potencia de 2 y, en general, más grande (o igual) que el tamaño del bloque del disco. Esto significa que una de sus lecturas de transmisión podría resultar en múltiples lecturas de bloques de disco, pero esas lecturas siempre usarán un bloque completo, sin lecturas desperdiciadas.

Asegurar esto también suele dar como resultado otros parámetros favorables al rendimiento que afectan tanto a la lectura como al procesamiento posterior: alineación del ancho del bus de datos, alineación de DMA, alineación de la línea de caché de memoria, número total de páginas de memoria virtual.

contestado el 23 de mayo de 17 a las 13:05

  1. Al menos en mi caso, la suposición es que el sistema subyacente está usando un búfer cuyo tamaño también es una potencia de dos, por lo que es mejor probar y hacer coincidir. Creo que hoy en día los búferes deberían hacerse un poco más grandes de lo que "la mayoría" de los programadores tienden a hacer. Iría con 32 KB en lugar de 4, por ejemplo.
  2. Lamentablemente, es muy difícil saberlo de antemano. Depende de si su aplicación está vinculada a E/S o CPU, por ejemplo.

contestado el 22 de mayo de 12 a las 09:05

No lo necesito por adelantado. Estoy bien con encontrarlo en tiempo de ejecución - Baruch

  1. Creo que principalmente es solo elegir un número "redondo". Si las computadoras trabajaran en decimal, probablemente elegiríamos 1000 o 10000 en lugar de 1024 o 8192. No hay una muy buena razón.

Una posible razón es que los sectores del disco suelen tener un tamaño de 512 bytes, por lo que leer un múltiplo de eso es más eficiente, suponiendo que todas las capas de hardware y el almacenamiento en caché hacen que el código de bajo nivel realmente pueda usar este hecho de manera eficiente. Lo cual probablemente no pueda a menos que esté escribiendo un controlador de dispositivo o haciendo una lectura sin búfer.

contestado el 22 de mayo de 12 a las 09:05

No hay ninguna razón que yo sepa que tiene que ser una potencia de dos. Está limitado por el tamaño del búfer que tiene que estar dentro del máximo size_t pero es poco probable que esto sea un problema.

Claramente, cuanto más grande sea el búfer, mejor, pero obviamente esto no es escalable, por lo que se deben tener en cuenta las consideraciones de recursos del sistema, ya sea en tiempo de compilación o, preferiblemente, en tiempo de ejecución.

contestado el 22 de mayo de 12 a las 09:05

1 . ¿Hay alguna razón por la que tiene que/debería ser una potencia de 2, o es solo la inclinación natural del programador a las potencias de 2?

Realmente no. Probablemente debería ser algo que coincida con el tamaño del ancho del bus de datos para simplificar la copia de la memoria, por lo que cualquier cosa que se divida en 16 sería buena con la tecnología actual. Usar una potencia de 2 hace que sea probable que funcione bien con cualquier tecnología futura.

2 . ¿Cuál sería el número "ideal"? Por "ideal" quiero decir que sería el más rápido.

Lo más rápido sería tanto como sea posible. Sin embargo, una vez que supere unos pocos kilobytes, tendrá una diferencia de rendimiento muy pequeña en comparación con la cantidad de memoria que utiliza.

Supongo que tendría que ser un múltiplo del tamaño del búfer del dispositivo subyacente. ¿O tal vez del búfer del objeto de flujo subyacente? ¿Cómo determinaría cuál es el tamaño de esos búferes, de todos modos?

Realmente no puede saber el tamaño de los búferes subyacentes, o depender de que sigan siendo los mismos.

Y una vez que lo haga, ¿el uso de un múltiplo aumentaría la velocidad con respecto al uso del tamaño exacto?

Algunos, pero muy pocos.

contestado el 22 de mayo de 12 a las 10:05

Creo que el tamaño ideal del búfer es el tamaño de un bloque en su disco duro, para que pueda asignarse correctamente con su búfer mientras almacena o recupera datos del disco duro.

contestado el 22 de mayo de 12 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.