2011-02-04 17 views
18

Estoy considerando usar la herencia virtual en una aplicación en tiempo real. ¿El uso de herencia virtual tiene un impacto en el rendimiento similar al de llamar a una función virtual? Los objetos en cuestión solo se crearían al inicio, pero me preocupa si todas las funciones de la jerarquía se enviarán a través de un vtable o si solo las de la clase base virtual.Impacto del rendimiento de la herencia virtual

+1

A menos que utilice la herencia múltiple, en realidad no hay necesidad de utilizar la herencia virtual. –

+0

@ ZaHowland, a menos que esté usando burlas con Google Test. (gtest) –

+3

@Amigable: no hay "a menos". Al utilizar Google Test, solo utiliza la herencia virtual cuando se trata de herencia múltiple. –

Respuesta

22

implementaciones comunes harán que el acceso a miembros de datos de clases base virtuales utilizan una indirección adicional.

Como señala James en sus comentarios, al llamar a una función miembro de una clase base en un escenario de herencia múltiple necesitará el ajuste del puntero this, y si esa clase base es virtual, entonces el desplazamiento de la clase base sub- objeto en el objeto de la clase derivada depende del tipo dinámico de la clase derivada y deberá calcularse en tiempo de ejecución.

si esto tiene ningún impacto en el rendimiento visible en aplicaciones del mundo real depende de muchas cosas:

  • Hacer bases virtuales tener miembros de datos en absoluto? A menudo, son las clases base abstractas las que deben derivarse virtualmente, y las bases abstractas que tienen miembros de datos a menudo son un olor de código.

  • suponiendo que tiene bases virtuales con miembros de datos, se accede a los en una ruta crítica? Si un usuario hace clic en algún botón de una GUI, se producen algunas docenas de indirecciones adicionales, nadie se dará cuenta.

  • ¿Cuál sería la alternativa si se evitan las bases virtuales? No solo el diseño puede ser inferior, también es probable que el diseño alternativo tenga un impacto en el rendimiento. Tiene que lograr el mismo objetivo, después de todo, y TANSTAAFL. Luego cambiaste una pérdida de rendimiento por otra más un diseño inferior.


Nota adicional: un vistazo a Stan Lippmann de Inside the C++ Object Model, que responde a estas preguntas muy a fondo.

+0

Para aclarar, ¿solo las llamadas a los miembros/funciones de las clases base virtuales dan como resultado una indirección adicional? – Graeme

+0

@Graeme: Ciertamente no soy un experto en esta área, pero no veo cómo las llamadas a las funciones _ de miembro de la clase base virtual darían como resultado una pérdida de rendimiento. Se envían estáticamente ('B :: f()') o dinámicamente a través de la tabla virtual de la clase derivada, al igual que las funciones miembro de bases no virtuales. ICBWT. – sbi

+1

@sbi: si la función no es virtual, entonces la función a llamar se puede seleccionar estáticamente, pero el puntero 'this' debe calcularse [o buscarse] en tiempo de ejecución, ¿verdad? –

0

¿Estás seguro de que te refieres a la herencia virtual? Si es así, es idéntico al costo de una llamada de función virtual normal. La búsqueda encadenada de vtable solo sigue una ruta especificada.

Dijiste que esto fue al inicio. Su sobrecarga de disco (desde simplemente cargar su código en la memoria) es probable que requiera órdenes de magnitud más de tiempo que la media docena de instrucciones, más o menos para las búsquedas vtable. Me sorprendería algo si pudieras perfilar esto y detectar una diferencia.

3

Eche un vistazo al siguiente estudio experimental a gran escala publicado OOPSLA'96. Estoy copiando una entrada de bibtex, el resumen y un enlace al documento. Consideraría que este es el estudio experimental más completo sobre el tema hasta la fecha.

@article{driesen1996direct, 
    title={{The direct cost of virtual function calls in C++}}, 
    author={Driesen, K. and H{\\"o}lzle, U.}, 
    journal={ACM Sigplan Notices}, 
    volume={31}, 
    number={10}, 
    pages={306--323}, 
    issn={0362-1340}, 
    year={1996}, 
    publisher={ACM} 
} 

Resumen: se estudia el coste directo de la función virtual llamadas en programas en C++, asumiendo el implementación estándar utilizando tablas de funciones virtuales. Nosotros medimos esta sobrecarga experimentalmente para una serie de grandes programas de referencia de , usando una combinación de inspección ejecutable y simulación de procesador. Nuestros resultados de muestran que los programas de C++ medidos gastan una mediana de del 5,2% de su tiempo y el 3,7% de sus instrucciones en el código de envío. Para las versiones de los programas "todos virtuales" , la sobrecarga media se eleva a 13.7% (13% de las instrucciones). La variante "thunk" de la implementación de la tabla de funciones virtuales reduce la sobrecarga en una mediana de 21% con respecto a la implementación estándar . En los procesadores futuros, estos los gastos generales es probable que aumenten moderadamente

http://www.cs.ucsb.edu/~urs/oocsb/papers/oopsla96.pdf

+1

+1 para la buena referencia. –

+4

No me sorprendería que las optimizaciones del compilador hayan dejado obsoleto este estudio. Fue publicado en 1996. –

+6

Um. Pero la pregunta era sobre ___virtual inheritance___, no sobre ___virtual functions___. – sbi

Cuestiones relacionadas