gpt4 book ai didi

c++ - SSE 加载相邻值

转载 作者:太空宇宙 更新时间:2023-11-04 11:33:24 29 4
gpt4 key购买 nike

在处理二维数组时,一个常见的事情是加载一组值,然后将它们向左或向右移动,然后再将 1 个值加载到不再需要的值中。执行此操作的最佳方法是什么?

float arr[128][128];

for(int i = 1;i < 127;++i)
for(int j = 1;j < 127;++j)
{
__m128 top = _mm_load_ps(arr[i - 1][j]);
__m128 center = _mm_load_ps(arr[i][j]);

//...stuff

//rotate the top
top = _mm_shuffle_ps(top,top,_MM_SHUFFLE(0,3,2,1));
//how do i load another item in without insert?

最佳答案

如果您正在谈论对 2D 数据进行邻域运算,那么要获得向左或向右移动一定量的 vector ,您可以使用未对齐的负载,或者如果您可以假设 SSSE3 或更高版本,请使用 _mm_alignr_epi8。通常,您只能在 SSE3 或更低版本的旧 CPU 上使用未对齐加载方法,而您别无选择。

对向左/向右移动 1 个浮点元素的 vector 进行操作的示例:

未对齐的负载:

for (int j = 0; j < 128; j += 4)
{
vl = _mm_loadu_ps(&a[i][j-1]); // left shifted vector
vm = _mm_load_ps(&a[i][j]); // middle vector
vr = _mm_loadu_ps(&a[i][j+1]); // right shifted vector
}

_mm_alignr_epi8:

va = _mm_setzero_ps();
vb = _mm_load_ps(&a[i][0]);
for (int j = 0; j < 128; j += 4)
{
vc = _mm_load_ps(&a[i][j+4]);
vl = _mm_alignr_epi8(va, vb, sizeof(float)); // left shifted vector
// middle vector = vb
vr = _mm_alignr_epi8(vb, vc, 3 * sizeof(float)); // right shifted vector
va = vb; // shuffle source vectors left by one
vb = vc;
}

请注意,当您执行大量具有大量不同移位的邻域操作时,有时临时转置整个数据 block 会更有效,这样您只需使用行索引而不是必须执行水平 vector 操作,例如以上。

关于c++ - SSE 加载相邻值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23728968/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com