Depending on how the specific operating system works, you generally expect the memory to be allocated unoptimized such that when you call for a byte, or a word or some other small data type to be allocated, the value occupies an entire register all of it's very own. How your compiler or interpreter works to interpret this however is something else, so if you were to compile a program in C# for instance, the value might physically occupy a register for itself, however the value will be boundary checked to ensure you don't try to store a value that will exceed the bounds of the intended datatype.
Performance-wise, and if you are really pedantic about such things, it's likely faster to simply use the datatype that most closely matches the target register size, but then you miss out on all of that lovely syntactic sugar that makes working with variables so easy.
How does this help you? Well, it's really up to you to decide what sort of situation you are coding for. For nearly every program I have ever written, it's enough to simply trust your compiler to optimize things and to use the datatype that is most useful to you. If you need high precision, use the larger floating point data types. If working with only positive values, you can probably use an unsigned integer, but for the most part, simply using the int datatype is enough.
If however you have some very strict data requirements, such as writing a communications protocol, or some sort of encryption algorithm, then using range-checked datatypes can come in very handy, particularly if you are trying to avoid problems relating to data overruns/underruns, or invalid data values.
The only other reason I can think of off the top of my head to use specific datatypes is when you are trying to communicate intent within your code. If you use a shortint for example, you are telling other developers that you are allowing positive and negative numbers within a very small value range.