2010-04-17 12 views
8

Actualmente, asigno mi memoria para matrices utilizando el MS específico mm_malloc. Alineé la memoria, ya que estoy haciendo algunas operaciones pesadas de matemáticas y la vectorización aprovecha la alineación. Me preguntaba si alguien sabe cómo sobrecargar al nuevo operador para hacer lo mismo, ya que me siento sucio malloc en todas partes (¿y finalmente me gustaría compilar también en Linux)? Gracias por cualquier ayudadevolviendo la memoria alineada con la nueva?

Respuesta

10

En primer lugar, es importante tener en cuenta que new y delete se pueden sobrecargar de forma global, o solo para una sola clase. Ambos casos se muestran en this article. También es importante tener en cuenta que si sobrecarga new casi seguramente también desea sobrecargar delete.

Hay algunas notas importantes sobre operator new y operator delete:

  1. El estándar de C++ requiere que un puntero válido se devuelve incluso si el tamaño que se le pasa es 0.
  2. También hay operator new[] y operator delete[], así que no te olvides de sobrecargarlos.
  3. Las clases derivadas heredan operator new y sus hermanos, así que asegúrese de anularlas.

En efectiva C++, punto 8, Scott Meyers incluye algunos ejemplos pseudocodish:

void * operator new(size_t size)  // your operator new might 
{          // take additional params 
    if (size == 0) {      // handle 0-byte requests 
    size = 1;       // by treating them as 
    }          // 1-byte requests 
    while (1) { 
    attempt to allocate size bytes; 
    if (the allocation was successful) 
     return (a pointer to the memory); 

    // allocation was unsuccessful; find out what the 
    // current error-handling function is (see Item 7) 
    new_handler globalHandler = set_new_handler(0); 
    set_new_handler(globalHandler); 

    if (globalHandler) (*globalHandler)(); 
    else throw std::bad_alloc(); 
    } 
} 


void operator delete(void *rawMemory) 
{ 
    if (rawMemory == 0) return; // do nothing if the null 
           // pointer is being deleted 
    deallocate the memory pointed to by rawMemory; 
    return; 
} 

Para obtener más información, sin duda me levanto eficaz C++.

+0

Entonces, ¿lo pondría en un encabezado y haría referencia a ese encabezado en todos mis archivos? – Steve

+0

Bueno, pondría las definiciones en un archivo fuente, pero sí. – rlbond

+0

solo una pequeña nota al pie: también puede definir un 'operador nuevo (tamaño_t conteo, tamaño_t alineación)' para que pueda pasar explícitamente la alineación como un argumento al operador nuevo. Esto se llamaría como 'nuevo (alineación) AlignedType' – user666412

2

new es necesario devolver un pointer [...] suitably aligned so that it can be converted to a pointer of any complete object type (§3.7.3.1 del estándar).

FWIW, C++ 0x agregará un alignof que le dirá la alineación necesaria para un tipo particular.

+3

Desafortunadamente, por alguna razón que nunca he entendido, los compiladores generalmente no aplican esta regla para los tipos SIMD de 128 bits. Por lo general, todavía están '' nuevos'' con una alineación de 8 bytes, creo. – jalf

+0

@jalf: dos razones: (1) cuanto más alineadas sean las asignaciones, mayor será la sobrecarga de asignación por bloque. Si realiza una gran cantidad de asignaciones de 17 bytes, verá una diferencia entre alineación 16 y solo 4 alineación. (2) (específico de GNU), glibc hace menos suposiciones específicas de la plataforma que GCC, y realmente no sabe ni le importa cuál es el tipo más grande que algún compilador de un sistema pueda soportar. Pero GCC "quiere" pasar malloc directamente a glibc, no agregar su propio mecanismo de alineación, con incluso más sobrecarga que hacerlo malloc. Leí un argumento público interesante al respecto en alguna parte. –

+0

...finalmente, el compilador en teoría podría elegir simplemente alinear llamadas a 'nuevo SIMD_Type', evitando la sobrecarga en todas las asignaciones de más de 15 bytes. Pero eso todavía estaría mal, porque si vas a hacer eso, entonces también deberías alinear las llamadas a 'new char [sizeof (SIMD_Type)]'. El consenso es pretender que los tipos SIMD no son "tipos propios adecuados", son cosas especiales que deben asignarse especialmente. –

Cuestiones relacionadas