【发布时间】:2021-10-31 20:34:31
【问题描述】:
我在一个测试程序中有以下两个结构:
typedef struct fltptr {
size_t size;
float *a;
float *b;
} fptr;
struct fltWrap256 {
__m256 *m256;
__m128 *m128;
float *m32;
};
typedef struct fltwrap {
struct fltWrap256 a;
struct fltWrap256 b;
} fwrap;
“fwrap”的重点是提供一种“SIMD”方式来访问“fptr”实例的相等但大小可变的浮点“数组”。 SIMD_point_to( fptr* , fwrap* ) 函数将适当地指向包装器实例的成员指针:
void SIMD_point_to( fptr *v, fwrap *S )
{
S->a.m256 = (__m256 *)(v->a);
S->b.m256 = (__m256 *)(v->b);
uint8_t rem = v->size % 8;
size_t offset = v->size - rem;
S->a.m128 = (__m128 *)(v->a + offset);
S->b.m128 = (__m128 *)(v->b + offset);
rem %= 4;
offset = v->size - rem;
S->a.m32 = v->a + offset;
S->b.m32 = v->b + offset;
}
视觉示例:
let fptr.a/b = [XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX]
m256*^(8x3) (4x1)m128*^ ^m32*(1x3)
let fptr.a/b = [XXXXX]
(8x0)m256*^ ^m32*(1x1)
(4x1)m128*^
但是因为 SIMD 需要 16 字节对齐,所以在分配 fptr.x 时需要使用 aligned_alloc( )。至少这是我认为我需要做的。
int main( )
{
fptr test;
//allocated size explicitly a multiple of 16(4x24=96) as required. Working size will be 23 floats.
test.a = aligned_alloc(16, 16, sizeof(float)*24 );
test.b = aligned_alloc(16, 16, sizeof(float)*24 );
test.size = 23;
/* Filling test.a/b */
float A[23] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f };
float B[23] = { 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, 110.0f, 111.0f, 112.0f, 113.0f, 114.0f, 115.0f, 116.0f, 117.0f, 118.0f, 119.0f, 120.0f, 121.0f, 122.0f, 123.0f };
memcpy( test.a, A, sizeof(float)*23 );
memcpy( test.b, B, sizeof(float)*23 );
fwrap wrap;
SIMD_point_to( &test, &wrap );
float __attribute__(( aligned(16) )) out[8];
/*
__m256 mout = _mm256_add_ps( wrap.a.m256[0], wrap.b.m256[0] ); //Seg Fault here
__m256_store_ps( out, mout );
*/
/*__m256_store_ps( out, wrap.a.m256[1] );*/ //Another here
__m256_storeu_ps( out, wrap.b.m256[1] ); //THIS WORKS!
for( int i = 0; i < 8; i++ )
printf("%f\n", out[i]);
/*
out[] contains the second set of 8 floats pointed to by 'wrap.b.m256'.
*/
}
storeu 不会抛出错误,但这只是意味着我做错了什么。有什么建议吗?
编辑:有趣的是,使用 '-O3' (gcc) 进行编译可以解决 store 的段错误,但不能解决 _mm256_add_ps。
【问题讨论】:
-
编辑问题以提供minimal reproducible example。显示重现问题的完整代码;不要只是描述它。
-
请粘贴
SIMD_point_to -
我的错,请参阅更新的操作。 @tstanisl
-
传递 3 个指针的结构似乎比指针 + 长度更糟糕,并且当您真正想要循环它时进行动态计算,除非您只将这些用于本地变量或用于内联。
-
在 GCC 命令行中添加
-fno-strict-aliasing标志是否有效?
标签: c pointers malloc simd memory-alignment