В параллельном программировании данных принято говорить о «Структуре массивов» (SOA) и «Массив структур» (AOS), где первый из двух примеров - AOS, а второй - SOA. Многие парадигмы параллельного программирования, в частности парадигмы в стиле SIMD, предпочитают SOA.
При программировании на GPU причина, по которой SOA обычно предпочитается, заключается в оптимизации доступа к глобальной памяти. Вы можете просмотреть записанную презентацию на Advanced CUDA C от GTC в прошлом году для подробного описания того, как GPU обращается к памяти.
Суть в том, что транзакции памяти имеют минимальный размер 32 байта, и вы хотите максимизировать эффективность каждой транзакции.
С AOS:
position[base + tid].x = position[base + tid].x + velocity[base + tid].x * dt;
// ^ write to every third address ^ read from every third address
// ^ read from every third address
С SOA:
position.x[base + tid] = position.x[base + tid] + velocity.x[base + tid] * dt;
// ^ write to consecutive addresses ^ read from consecutive addresses
// ^ read from consecutive addresses
Во втором случае, чтение с последовательных адресов означает, что вы имеете 100% эффективность против 33% в первом случае. Обратите внимание, что на старых графических процессорах (с возможностью вычислений 1.0 и 1.1) ситуация намного хуже (эффективность 13%).
Существует еще одна возможность - если в структуре было два или четыре числа с плавающей запятой, вы можете прочитать AOS со 100% эффективностью:
float4 lpos;
float4 lvel;
lpos = position[base + tid];
lvel = velocity[base + tid];
lpos.x += lvel.x * dt;
//...
position[base + tid] = lpos;
Опять же, ознакомьтесь с презентацией Advanced CUDA C для подробностей.