在一個測驗程式中,我有以下兩個結構:
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'實體的相等但大小可變的浮點'陣列'。
void SIMD_point_to( fptr *v, fwrap *S )/span>
{
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 = [XXXXXXXXXXXXXXXXXX]
m256*^(8x3) (4x1)m128*^^m32*(1x3)
讓fptr.a/b=[XXXX]
(8x0)m256*^ ^m32*(1x1)
(4x1)m128*^
但是因為SIMD需要16位元組的對齊方式,我需要在分配aligned_alloc( )時使用fptr.x。至少我認為這是我需要做的。
int main( )
{
fptr 測驗。
//按要求明確分配大小為16的倍數(4x24=96)。作業大小將是23個浮點數。
test.a = aligned_alloc(16, 16, sizeof(float)*24 ) 。
test.b = aligned_alloc(16, 16, sizeof(float)*24 ) 。
test.size = 23;
/* 填寫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包裝。
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
", out[i])。)
/*
out[] 包含第二組由'wrap.b.m256'指向的8個浮點。
*/
}
storeu沒有拋出一個錯誤,但這只是意味著我做錯了什么。有什么建議嗎?
編輯:有趣的是,用'-O3'(gcc)編譯可以解決store的seg故障,但不能解決_mm256_add_ps。
uj5u.com熱心網友回復:
來自man aligned_alloc.
函式aligned_alloc()與memalign()相同,只是增加了一個限制,即大小應該是alignment的倍數。
我猜想aligned_alloc回傳NULL,因為sizeof(float)*23不能被16整除。當使用指標時,這將導致 segfault。
只要將sizeof(float)*23取整到16的下一個倍數即可。
一種方法是:
(sizeof(float)*23 16 - 1) / 16 * 16
另一個問題是float out[8];的正確對齊。
為了強制對齊與__m256兼容,可以使用C11中的_Alignas關鍵字。
_Alignas (__m256) float out[8] 。
編輯
正如評論中所建議的,對齊要求可以用更漂亮的形式來寫:
...
alignas (__m256) float out[8]。
uj5u.com熱心網友回復:
為什么你只嘗試按16對齊?__m256需要32位元組對齊
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/315482.html
標籤:
下一篇:將地址轉換為指標的問題
