@@ -130,7 +130,7 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
130130 accum_2 = _mm512_setzero_ps ();
131131 accum_3 = _mm512_setzero_ps ();
132132
133- // alignment has side-effect when the size of input array is not large enough
133+ // shorter unrolled path for small inputs
134134 if (n2 < 256 ) {
135135 if (n2 >= 128 ) {
136136 x00 = _mm512_loadu_ps (& x1 [ 0 ]);
@@ -217,29 +217,22 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
217217
218218 sumf = _mm512_reduce_add_ps (accum_0 );
219219 }
220- // n2 >= 256, doing alignment
220+ /* n2 >= 256. Deliberately no peeling to an alignment boundary:
221+ peeling makes the grouping of the sum into accumulators - and
222+ hence the rounding of the result - depend on the buffer address.
223+ Unaligned loads keep the result a function of n alone, and cost
224+ the same as aligned loads when the address happens to be
225+ aligned. */
221226 else {
222227
223- int align_header = ((64 - ((uintptr_t )x1 & (uintptr_t )0x3f )) >> 2 ) & 0xf ;
224-
225- if (0 != align_header ) {
226- uint16_t align_mask16 = (((uint16_t )0xffff ) >> (16 - align_header ));
227- x00 = _mm512_maskz_loadu_ps (* ((__mmask16 * ) & align_mask16 ), & x1 [0 ]);
228- x00 = _mm512_and_ps (x00 , abs_mask );
229- accum_0 = _mm512_add_ps (accum_0 , x00 );
230-
231- n2 -= align_header ;
232- x1 += align_header ;
233- }
234-
235- x00 = _mm512_load_ps (& x1 [ 0 ]);
236- x01 = _mm512_load_ps (& x1 [ 16 ]);
237- x02 = _mm512_load_ps (& x1 [ 32 ]);
238- x03 = _mm512_load_ps (& x1 [ 48 ]);
239- x04 = _mm512_load_ps (& x1 [ 64 ]);
240- x05 = _mm512_load_ps (& x1 [ 80 ]);
241- x06 = _mm512_load_ps (& x1 [ 96 ]);
242- x07 = _mm512_load_ps (& x1 [112 ]);
228+ x00 = _mm512_loadu_ps (& x1 [ 0 ]);
229+ x01 = _mm512_loadu_ps (& x1 [ 16 ]);
230+ x02 = _mm512_loadu_ps (& x1 [ 32 ]);
231+ x03 = _mm512_loadu_ps (& x1 [ 48 ]);
232+ x04 = _mm512_loadu_ps (& x1 [ 64 ]);
233+ x05 = _mm512_loadu_ps (& x1 [ 80 ]);
234+ x06 = _mm512_loadu_ps (& x1 [ 96 ]);
235+ x07 = _mm512_loadu_ps (& x1 [112 ]);
243236
244237 n2 -= 128 ;
245238 x1 += 128 ;
@@ -251,26 +244,26 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
251244 x03 = _mm512_and_ps (x03 , abs_mask );
252245
253246 accum_0 = _mm512_add_ps (accum_0 , x00 );
254- x00 = _mm512_load_ps (& x1 [ 0 ]);
247+ x00 = _mm512_loadu_ps (& x1 [ 0 ]);
255248 accum_1 = _mm512_add_ps (accum_1 , x01 );
256- x01 = _mm512_load_ps (& x1 [ 16 ]);
249+ x01 = _mm512_loadu_ps (& x1 [ 16 ]);
257250 accum_2 = _mm512_add_ps (accum_2 , x02 );
258- x02 = _mm512_load_ps (& x1 [ 32 ]);
251+ x02 = _mm512_loadu_ps (& x1 [ 32 ]);
259252 accum_3 = _mm512_add_ps (accum_3 , x03 );
260- x03 = _mm512_load_ps (& x1 [ 48 ]);
253+ x03 = _mm512_loadu_ps (& x1 [ 48 ]);
261254
262255 x04 = _mm512_and_ps (x04 , abs_mask );
263256 x05 = _mm512_and_ps (x05 , abs_mask );
264257 x06 = _mm512_and_ps (x06 , abs_mask );
265258 x07 = _mm512_and_ps (x07 , abs_mask );
266259 accum_0 = _mm512_add_ps (accum_0 , x04 );
267- x04 = _mm512_load_ps (& x1 [ 64 ]);
260+ x04 = _mm512_loadu_ps (& x1 [ 64 ]);
268261 accum_1 = _mm512_add_ps (accum_1 , x05 );
269- x05 = _mm512_load_ps (& x1 [ 80 ]);
262+ x05 = _mm512_loadu_ps (& x1 [ 80 ]);
270263 accum_2 = _mm512_add_ps (accum_2 , x06 );
271- x06 = _mm512_load_ps (& x1 [ 96 ]);
264+ x06 = _mm512_loadu_ps (& x1 [ 96 ]);
272265 accum_3 = _mm512_add_ps (accum_3 , x07 );
273- x07 = _mm512_load_ps (& x1 [112 ]);
266+ x07 = _mm512_loadu_ps (& x1 [112 ]);
274267
275268 n2 -= 128 ;
276269 x1 += 128 ;
@@ -296,10 +289,10 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
296289 accum_3 = _mm512_add_ps (accum_3 , x07 );
297290
298291 if (n2 >= 64 ) {
299- x00 = _mm512_load_ps (& x1 [ 0 ]);
300- x01 = _mm512_load_ps (& x1 [16 ]);
301- x02 = _mm512_load_ps (& x1 [32 ]);
302- x03 = _mm512_load_ps (& x1 [48 ]);
292+ x00 = _mm512_loadu_ps (& x1 [ 0 ]);
293+ x01 = _mm512_loadu_ps (& x1 [16 ]);
294+ x02 = _mm512_loadu_ps (& x1 [32 ]);
295+ x03 = _mm512_loadu_ps (& x1 [48 ]);
303296 x00 = _mm512_and_ps (x00 , abs_mask );
304297 x01 = _mm512_and_ps (x01 , abs_mask );
305298 x02 = _mm512_and_ps (x02 , abs_mask );
@@ -314,8 +307,8 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
314307 }
315308
316309 if (n2 >= 32 ) {
317- x00 = _mm512_load_ps (& x1 [ 0 ]);
318- x01 = _mm512_load_ps (& x1 [16 ]);
310+ x00 = _mm512_loadu_ps (& x1 [ 0 ]);
311+ x01 = _mm512_loadu_ps (& x1 [16 ]);
319312 x00 = _mm512_and_ps (x00 , abs_mask );
320313 x01 = _mm512_and_ps (x01 , abs_mask );
321314 accum_0 = _mm512_add_ps (accum_0 , x00 );
@@ -326,7 +319,7 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
326319 }
327320
328321 if (n2 >= 16 ) {
329- x00 = _mm512_load_ps (& x1 [ 0 ]);
322+ x00 = _mm512_loadu_ps (& x1 [ 0 ]);
330323 x00 = _mm512_and_ps (x00 , abs_mask );
331324 accum_0 = _mm512_add_ps (accum_0 , x00 );
332325
@@ -336,7 +329,7 @@ static FLOAT casum_kernel(BLASLONG n, FLOAT *x)
336329
337330 if (n2 ) {
338331 uint16_t tail_mask16 = (((uint16_t ) 0xffff ) >> (16 - n2 ));
339- x00 = _mm512_maskz_load_ps (* ((__mmask16 * ) & tail_mask16 ), & x1 [ 0 ]);
332+ x00 = _mm512_maskz_loadu_ps (* ((__mmask16 * ) & tail_mask16 ), & x1 [ 0 ]);
340333 x00 = _mm512_and_ps (x00 , abs_mask );
341334 accum_0 = _mm512_add_ps (accum_0 , x00 );
342335 }
0 commit comments