Начнем с того, что это регистры. По сути отличие между ними в том, что xmm (128 bits) хранит меньше данных, чем ymm (256 bits).
Вы можете встретить такое в burst-generated коде, когда разглядываете бесконечные регистры в инспекторе берста.
Пример:
struct MyStruct { public float a1; public float a2; public float a3; public float a4; }
myStruct1 = myStruct2 будет использовать xmm (4 флота в 128 битах).
Если же добавить полей:
struct MyStruct { public float a1; public float a2; public float a3; public float a4; public float a5; public float a6; public float a7; public float a8; }
то теперь myStruct1 = myStruct2 будет использовать ymm (8 флотов в 256 битах).
Таким образом, мы считаем за одну операцию больше данных.
Но если же мы оставим 6 полей, то будет использован один vmovups xmm, а остальные два поля будут считываться mov rdx.