Estás confundiendo dos problemas diferentes. Puede pasar cualquier objeto por valor (siempre que se pueda copiar).
Si se aprobará o no en un registro o en la pila depende de la implementación y, específicamente, de la convención de llamadas utilizada.
En algunas convenciones de llamada, los parámetros de más de 8 bytes (el tamaño de registro de propósito general) se pasarán en la pila. En virtud de otras convenciones de llamadas, es posible que simplemente se dividan en varios registros.
Debajo de algunos, es posible que los objetos sean nunca pasados en registros, independientemente de su tamaño.
Del mismo modo, los valores SIMD (SSE/AVX) pueden ser pasados en registros en algunas convenciones de llamada, pero siempre se ponen en la pila en otros. Y lo mismo puede ser cierto para los valores escalares de coma flotante.
Pero lo que estás preguntando realmente no puede ser respondido de manera significativa. La velocidad de copia de un objeto se ve afectada por el tamaño del objeto, sí.Si el objeto es un tipo POD, y cabe en un registro, entonces puede copiarse con una simple instrucción mov
. Si el compilador hará o no do que depende del compilador.
Y, obviamente, cuanto mayor sea el objeto, más espacio de memoria caché ocupará, lo que significa que obtendrá más errores de caché.
Pero esto es tan vago que es inútil. No sabemos cómo se ve su objeto, y no sabemos cuál es su código con. Si tiene un tipo específico en mente, escriba un punto de referencia para ver cómo lo maneja el compilador.
En respuesta a su edición
me interesa si hay algún tipo de recomendación general cuando se trata de parámetros de traspaso conocer la arquitectura, tamaño de letra, tamaño de caché, etc. Algo así como: "Prefiero pasar el tipo de valor cuando es menor que N bytes.
en primer lugar, confía en tu compilador. se optimizará agresiva copias de distancia, en muchas situaciones, por lo que incluso si hace pasar un objeto grande en valor, eso Es poco probable que sea un problema mensurable.
En segundo lugar, está buscando una microoptimización que es poco probable que haga una notable diferencia en ambos sentidos. Para objetos pequeños, pasar por valor evita un indirecto de puntero, por lo que es probablemente un poco más rápido. En algún punto, esto se ve abrumado por el costo de copia (suponiendo que el objeto es copiado, ver arriba). Para muy objetos grandes (para el argumento, digamos 500 bytes o más, tan grande que los objetos normalmente no lo alcanzan), definitivamente debe pasar por referencia.
¿Pero para objetos de 8, 16, 24, 40 bytes? ¿Quién sabe? ¿A quien le importa? Es poco probable que se haga una diferencia medible en el código real.
que me lleva a las dos reglas de oro:
- hacer lo que parece natural: si pasando por copia hace que su código más simple o más limpio, hacer eso.
- si el rendimiento es importante, entonces (1) asegúrese de que lo que está viendo en realidad tiene cualquier impacto notable en su rendimiento. Mídelo. Si afecta el rendimiento, entonces puede medirse. Si no se puede medir, entonces la diferencia en el rendimiento, por definición, no puede ser perceptible.
Así, en pocas palabras:
- para este tipo de primitve, pasan por valor.
- para tipos muy grandes, pase por referencia.
- para todo lo demás, deja de preocuparte y pasa tu tiempo en algo productivo.
En algún punto, más allá de 8 bytes, el compilador genera código para crear una copia local y pasa un puntero a esa copia. Pruébelo, mire el código máquina generado. –