Difficile à dire ce qui va se passer exactement une fois le code compilé. Par exemple j'ai fait le test avec un code simple pour une fonction f(char) et une fonction f(char&), qui modifie son argument dans son corps:
http://pastebin.com/mQ5N795e
Dans les deux cas, lu très vite l'assembleur généré ne fait strictement ni l'un ni l'autre et effectue des manipulations direct sur la pile. En tout cas il n'y a pas de différence au niveau de cette fonction entre les deux codes. Et ça, c'est sans les optimisations.
De toute façon, y a l'alignement. Tu n'as peut-être besoin de passer qu'un byte, mais pour des raisons de rapidité il y a de bonnes chances que le compilo en balance de toute façon 4 à tous les coups. En bref, le langage te définit la sémantique, l'implémentation exacte tu n'en sauras rien.
Le seul piège dans l'histoire serait le raisonnement: "Je n'ai pas envie d'une sémantique de copie sur mon argument qui est un type primitif, donc je vais passer une référence constante à ma fonction, ce sera plus léger.". Je ne vois aucun cas où ça pourrait l'être, par contre avec un compilo pas malin assez ça peut faire pire. Ça a aussi le gros inconvénient de rendre le prototype moins clair.