2012-01-31 7 views
12

Alineado malloc es posix_memalign, eso está bien, pero ¿qué pasa con el alineado realloc? ¿Conserva realloc la alineación o cómo asegurar que la memoria reasignada tenga la misma alineación? Asume Linux y x86_64.¿Realloc mantiene la alineación de memoria de posix_memalign?

+2

No, si necesita una alineación particular, p. Ej. para datos SIMD, entonces no use realloc. –

+0

Entonces, si necesito "realloc alineado", debo liberar y posix_memalign nueva memoria, ¿verdad? – Cartesius00

+1

Sí, incluso podría implementar su propio 'posix_memrealloc' de esta manera si realmente quisiera. –

Respuesta

15

No, realloc en la memoria devuelta desde posix_memalign no está garantizado por ISO o POSIX para mantener la misma alineación. A reallocpuede simplemente expanda el bloque actual en la misma dirección, pero también puede mover el bloque a una dirección diferente cuya alineación sea menos estricta que la original.

Si desea la misma alineación, probablemente sea mejor asignar otro bloque y copiar los datos.

Desafortunadamente, no hay función de posix_memalign_realloc en la especificación de UNIX único.

Si no quiere pasar por la molestia de copiar datos cada vez, puede probar con el realloc(a) y, si la alineación de ese no fue el esperado, entonces y sólo entonces llame al posix_memalign para obtener una dirección alineada correctamente y copiar los datos allí, liberando la dirección anterior cuando haya terminado.

Esto puede resultar en:

  • cero copias (si el bloque actual se puede ampliar en el lugar);
  • una copia (si realloc copias pero sucede que le da un bloque alineado correctamente); o
  • dos copias (si realloc copias y luego también tiene que copiar debido a la desalineación).

Se puede también resultar en menos copia de lo indicado en función de la aplicación de gestión de memoria subyacente. Por ejemplo, una "copia" puede simplemente implicar la reasignación de bloques de memoria en lugar de mover físicamente los datos.

Así que es posible que desee conservar algunas estadísticas para ver si este esquema vale la pena.


(a) Hemos de tener en cuenta que ni POSIX ni Linux páginas man especificar si está o no aun puede pasar estos punteros a realloc, solo que se pueden pasar a free.

Sin embargo, basado en el código fuente de GNU libc actual, que parece funcionar, aunque eso no es garantía de que seguirá trabajando en el futuro :-)

Mi temor era que iba a asignar memoria normalmente (estándar de alineación) y devuelve una dirección de desplazamiento (es decir, no la dirección actaul asignada, sino una N bytes más allá) que free era lo suficientemente inteligente como para volver a la dirección real antes de tejer su magia.

Una forma de hacerlo sería almacenar la dirección actual inmediatamente antes de la dirección devuelta aunque esto, por supuesto, llevaría a desperdicio incluso para asignaciones regulares.

En ese caso, free puede haber sido hecha inteligente (ya que las especificaciones dicen que debe ser capaz de manejar las asignaciones hechas por posix_memalign) pero realloc pueden no haber tenido la misma inteligencia (ya que los documentos no dicen nada sobre ese asunto)

Sin embargo, basado en GNU glibc 2.14.1, en realidad asigna más memoria de la necesaria y luego juguetea con la arena para liberar el preespacio y el espacio posterior, de modo que la dirección devuelta es una dirección "real", utilizable por free o realloc.

Pero, como se indicó, la documentación no garantiza esto.

+0

Esta respuesta no es correcta de una manera importante: realloc por lo general no copia aunque se mueva el área de la memoria. Creo que si no hay suficiente espacio en la dirección de memoria actual para expandir un búfer, las páginas se vuelven a mapear para evitar una copia. Entonces sería cero copias, cero copias, una copia. –

+0

@RafaelBaptista, confunde algunas * implementaciones * con los * estándares. * No hay * nada * en los estándares (ISO/POSIX) que ordena cómo ocurren las cosas debajo de las cubiertas. Sin embargo, parece que la pregunta fue modificada después de mi respuesta para asumir Linux, lo que reduce un poco el campo (pero menos de lo que piensas ya que Linux se ejecuta en una gran variedad de hardware con opciones de MMU posiblemente variadas). Ajustará la respuesta a su gusto. – paxdiablo

1

realloc se comporta igual que malloc, por lo que la memoria devuelta por realloc tiene la misma restricción de alineación de malloc.

0

Si mira el código fuente de glibc para realloc, llama directamente a malloc. Entonces, la memoria se alinea de la misma manera que malloc.

+0

Lo siento, debería agregar. En la fuente, si hay espacio de montón adicional en la ubicación ya señalada por la memoria malloc'd original, entonces solo asigna un montón adicional al final del tamaño de asignación original sin llamar a malloc. Obviamente, esto no cambiará la alineación. –

Cuestiones relacionadas