如何协调双数组问题与硬件Gather/Scatter指令的特性?
数组拆分后的元素引用与SIMD Gather指令适配问题
单数组的原始实现
原本我有一个统一类型的数组,每个元素存储同数组内目标元素的索引,直接通过索引就能获取目标数据,操作非常直接:
struct type_1 { float data; int target_index; }; struct type_1 first_array[1024]; first_array[0].target_index = 1; // 目标为数组内的索引1 int target_index = first_array[0].target_index; float target_data = first_array[target_index].data;
使用Gather指令批量获取数据
这种单数组场景下,还能利用SIMD的Gather指令一次性获取4个float数据:
__m128i indices = _mm_setr_epi32(0, 1, 2, 3); __m128 _mm_i32gather_ps((void *)first_array, indices, 8);
(注:我通常会采用纯SoA布局来执行这类Gather操作,但这并非本次问题的核心关注点)
拆分双数组后的引用问题
现在需要把数组拆分成两种不同类型的数组:
struct type_1 { float data; int target_index; }; struct type_2 { float data; int target_index; }; struct type_1 first_array[512]; struct type_2 second_array[512];
这里的问题是,target_index无法区分属于哪个数组,没法直接定位到目标元素。
当前想到的解决方案
我想到的办法是给每个结构体添加一个枚举类型,标记目标元素所在的数组,访问时通过分支判断来定位:
enum target_type { TYPE_1, TYPE_2 }; struct type_1 { float data; int target_index; enum target_type target_type; }; struct type_2 { float data; int target_index; enum target_type target_type; }; struct type_1 first_array[512]; struct type_2 second_array[512]; first_array[0].target_index = 1; // 目标索引为1 first_array[0].target_type = TYPE_2; // 目标位于第二个数组 int target_index = first_array[0].target_index; float target_data; switch (first_array[0].target_type) { case TYPE_1: target_data = first_array[target_index].data; break; case TYPE_2: target_data = second_array[target_index].data; break; }
待解决的疑问
- 有没有更简洁的实现方式来处理双数组的元素引用?
- Gather/Scatter指令仅接受单个指针和一组索引,仅适用于单数组场景。拆分双数组后,该如何利用Gather指令?为什么这种简单的拆分会让这类SIMD指令完全失效?我是不是漏掉了什么关键点?
内容的提问来源于stack exchange,提问作者aganm
相关产品推荐
相关产品推荐

