diff --git a/raid.c b/raid.c index 4e756aa1..bbe25834 100644 --- a/raid.c +++ b/raid.c @@ -55,8 +55,8 @@ * R = sum(4^i * Di) * S = sum(8^i * Di) with 0<=i=0;--d) { p0 ^= v_32(vbuf[d][i]); p1 ^= v_32(vbuf[d][i+4]); @@ -264,6 +268,7 @@ void raid5_int64(unsigned char** vbuf, unsigned data, unsigned size) for(i=0;i=0;--d) { p0 ^= v_64(vbuf[d][i]); p1 ^= v_64(vbuf[d][i+8]); @@ -296,6 +301,7 @@ void raid5_sse2(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("movdqa %0,%%xmm1" : : "m" (vbuf[l][i+16])); asm volatile("movdqa %0,%%xmm2" : : "m" (vbuf[l][i+32])); asm volatile("movdqa %0,%%xmm3" : : "m" (vbuf[l][i+48])); + /* accessing disks in backward order doesn't affect speed */ for(d=l-1;d>=0;--d) { asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); asm volatile("movdqa %0,%%xmm5" : : "m" (vbuf[d][i+16])); @@ -559,9 +565,10 @@ void raid6_sse2ext(unsigned char** vbuf, unsigned data, unsigned size) /* * RAIDTP 8bit C implementation * - * Note that instead of a generic multiplicationt table, likely resulting in multiple cache misses, - * a precomputed table could be used. But this is only a kind of reference function, - * and we are not really interested on speed. + * Note that instead of a generic multiplicationt table, likely resulting + * in multiple cache misses, a precomputed table could be used. + * But this is only a kind of reference function, and we are not really + * interested in speed. */ void raidTP_int8(unsigned char** vbuf, unsigned data, unsigned size) { @@ -579,14 +586,22 @@ void raidTP_int8(unsigned char** vbuf, unsigned data, unsigned size) r = vbuf[data+2]; for(i=0;i=0;--d) { + p0 = q0 = r0 = 0; + for(d=l;d>0;--d) { d0 = v_8(vbuf[d][i]); p0 ^= d0; q0 ^= gfmul[d0][gfmatrix[1][d]]; r0 ^= gfmul[d0][gfmatrix[2][d]]; } + + /* first disk with all coefficients at 1 */ + d0 = v_8(vbuf[0][i]); + + p0 ^= d0; + q0 ^= d0; + r0 ^= d0; + v_8(p[i]) = p0; v_8(q[i]) = q0; v_8(r[i]) = r0; @@ -614,10 +629,25 @@ void raidTP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.mask[0])); for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %xmm4,%xmm0"); + asm volatile("movdqa %xmm4,%xmm1"); + + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("psraw $4,%xmm5"); + asm volatile("pand %xmm7,%xmm4"); + asm volatile("pand %xmm7,%xmm5"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm6" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm5,%xmm6"); + asm volatile("pxor %xmm6,%xmm2"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); asm volatile("pxor %xmm5,%xmm5"); @@ -641,6 +671,20 @@ void raidTP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pshufb %xmm5,%xmm6"); asm volatile("pxor %xmm6,%xmm2"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); + + asm volatile("pxor %xmm5,%xmm5"); + asm volatile("pcmpgtb %xmm1,%xmm5"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("pand %xmm3,%xmm5"); + asm volatile("pxor %xmm5,%xmm1"); + + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm2,%0" : "=m" (r[i])); @@ -673,13 +717,37 @@ void raidTP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("movdqa %0,%%xmm11" : : "m" (gfconst16.mask[0])); for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + asm volatile("movdqa %0,%%xmm12" : : "m" (vbuf[l][i+16])); + + asm volatile("movdqa %xmm4,%xmm0"); + asm volatile("movdqa %xmm4,%xmm1"); + asm volatile("movdqa %xmm12,%xmm8"); + asm volatile("movdqa %xmm12,%xmm9"); + + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("movdqa %xmm12,%xmm13"); + asm volatile("psraw $4,%xmm5"); + asm volatile("psraw $4,%xmm13"); + asm volatile("pand %xmm11,%xmm4"); + asm volatile("pand %xmm11,%xmm12"); + asm volatile("pand %xmm11,%xmm5"); + asm volatile("pand %xmm11,%xmm13"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("movdqa %xmm2,%xmm10"); + asm volatile("movdqa %xmm7,%xmm15"); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm12,%xmm10"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pshufb %xmm13,%xmm15"); + asm volatile("pxor %xmm7,%xmm2"); + asm volatile("pxor %xmm15,%xmm10"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); asm volatile("movdqa %0,%%xmm12" : : "m" (vbuf[d][i+16])); @@ -721,6 +789,29 @@ void raidTP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm7,%xmm2"); asm volatile("pxor %xmm15,%xmm10"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); + asm volatile("movdqa %0,%%xmm12" : : "m" (vbuf[0][i+16])); + + asm volatile("pxor %xmm5,%xmm5"); + asm volatile("pxor %xmm13,%xmm13"); + asm volatile("pcmpgtb %xmm1,%xmm5"); + asm volatile("pcmpgtb %xmm9,%xmm13"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("paddb %xmm9,%xmm9"); + asm volatile("pand %xmm3,%xmm5"); + asm volatile("pand %xmm3,%xmm13"); + asm volatile("pxor %xmm5,%xmm1"); + asm volatile("pxor %xmm13,%xmm9"); + + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("pxor %xmm12,%xmm8"); + asm volatile("pxor %xmm12,%xmm9"); + asm volatile("pxor %xmm12,%xmm10"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm8,%0" : "=m" (p[i+16])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); @@ -736,9 +827,10 @@ void raidTP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) /* * RAIDQP 8bit C implementation * - * Note that instead of a generic multiplicationt table, likely resulting in multiple cache misses, - * a precomputed table could be used. But this is only a kind of reference function, - * and we are not really interested on speed. + * Note that instead of a generic multiplicationt table, likely resulting + * in multiple cache misses, a precomputed table could be used. + * But this is only a kind of reference function, and we are not really + * interested in speed. */ void raidQP_int8(unsigned char** vbuf, unsigned data, unsigned size) { @@ -758,8 +850,8 @@ void raidQP_int8(unsigned char** vbuf, unsigned data, unsigned size) s = vbuf[data+3]; for(i=0;i=0;--d) { + p0 = q0 = r0 = s0 = 0; + for(d=l;d>0;--d) { d0 = v_8(vbuf[d][i]); p0 ^= d0; @@ -767,6 +859,15 @@ void raidQP_int8(unsigned char** vbuf, unsigned data, unsigned size) r0 ^= gfmul[d0][gfmatrix[2][d]]; s0 ^= gfmul[d0][gfmatrix[3][d]]; } + + /* first disk with all coefficients at 1 */ + d0 = v_8(vbuf[0][i]); + + p0 ^= d0; + q0 ^= d0; + r0 ^= d0; + s0 ^= d0; + v_8(p[i]) = p0; v_8(q[i]) = q0; v_8(r[i]) = r0; @@ -794,11 +895,32 @@ void raidQP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) s = vbuf[data+3]; for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.mask[0])); + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %xmm4,%xmm0"); + asm volatile("movdqa %xmm4,%xmm1"); + + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("psraw $4,%xmm5"); + asm volatile("pand %xmm7,%xmm4"); + asm volatile("pand %xmm7,%xmm5"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm2"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("pshufb %xmm4,%xmm3"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm3"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); @@ -832,6 +954,22 @@ void raidQP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm6,%xmm3"); asm volatile("pxor %xmm7,%xmm3"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); + + asm volatile("pxor %xmm5,%xmm5"); + asm volatile("pcmpgtb %xmm1,%xmm5"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("pand %xmm7,%xmm5"); + asm volatile("pxor %xmm5,%xmm1"); + + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("pxor %xmm4,%xmm3"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm2,%0" : "=m" (r[i])); @@ -864,15 +1002,49 @@ void raidQP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) s = vbuf[data+3]; for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm15" : : "m" (gfconst16.mask[0])); + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + asm volatile("movdqa %0,%%xmm12" : : "m" (vbuf[l][i+16])); + + asm volatile("movdqa %xmm4,%xmm0"); + asm volatile("movdqa %xmm4,%xmm1"); + asm volatile("movdqa %xmm12,%xmm8"); + asm volatile("movdqa %xmm12,%xmm9"); + + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("movdqa %xmm12,%xmm13"); + asm volatile("psraw $4,%xmm5"); + asm volatile("psraw $4,%xmm13"); + asm volatile("pand %xmm15,%xmm4"); + asm volatile("pand %xmm15,%xmm12"); + asm volatile("pand %xmm15,%xmm5"); + asm volatile("pand %xmm15,%xmm13"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("movdqa %xmm2,%xmm10"); + asm volatile("movdqa %xmm7,%xmm15"); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm12,%xmm10"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pshufb %xmm13,%xmm15"); + asm volatile("pxor %xmm7,%xmm2"); + asm volatile("pxor %xmm15,%xmm10"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("movdqa %xmm3,%xmm11"); + asm volatile("movdqa %xmm7,%xmm15"); + asm volatile("pshufb %xmm4,%xmm3"); + asm volatile("pshufb %xmm12,%xmm11"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pshufb %xmm13,%xmm15"); + asm volatile("pxor %xmm7,%xmm3"); + asm volatile("pxor %xmm15,%xmm11"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); asm volatile("movdqa %0,%%xmm15" : : "m" (gfconst16.mask[0])); asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); @@ -929,6 +1101,33 @@ void raidQP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm7,%xmm3"); asm volatile("pxor %xmm15,%xmm11"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + asm volatile("movdqa %0,%%xmm15" : : "m" (gfconst16.mask[0])); + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); + asm volatile("movdqa %0,%%xmm12" : : "m" (vbuf[0][i+16])); + + asm volatile("pxor %xmm5,%xmm5"); + asm volatile("pxor %xmm13,%xmm13"); + asm volatile("pcmpgtb %xmm1,%xmm5"); + asm volatile("pcmpgtb %xmm9,%xmm13"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("paddb %xmm9,%xmm9"); + asm volatile("pand %xmm7,%xmm5"); + asm volatile("pand %xmm7,%xmm13"); + asm volatile("pxor %xmm5,%xmm1"); + asm volatile("pxor %xmm13,%xmm9"); + + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("pxor %xmm4,%xmm3"); + asm volatile("pxor %xmm12,%xmm8"); + asm volatile("pxor %xmm12,%xmm9"); + asm volatile("pxor %xmm12,%xmm10"); + asm volatile("pxor %xmm12,%xmm11"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm8,%0" : "=m" (p[i+16])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); @@ -946,9 +1145,10 @@ void raidQP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) /* * RAIDPP 8bit C implementation * - * Note that instead of a generic multiplicationt table, likely resulting in multiple cache misses, - * a precomputed table could be used. But this is only a kind of reference function, - * and we are not really interested on speed. + * Note that instead of a generic multiplicationt table, likely resulting + * in multiple cache misses, a precomputed table could be used. + * But this is only a kind of reference function, and we are not really + * interested in speed. */ void raidPP_int8(unsigned char** vbuf, unsigned data, unsigned size) { @@ -970,8 +1170,8 @@ void raidPP_int8(unsigned char** vbuf, unsigned data, unsigned size) t = vbuf[data+4]; for(i=0;i=0;--d) { + p0 = q0 = r0 = s0 = t0 = 0; + for(d=l;d>0;--d) { d0 = v_8(vbuf[d][i]); p0 ^= d0; @@ -980,6 +1180,16 @@ void raidPP_int8(unsigned char** vbuf, unsigned data, unsigned size) s0 ^= gfmul[d0][gfmatrix[3][d]]; t0 ^= gfmul[d0][gfmatrix[4][d]]; } + + /* first disk with all coefficients at 1 */ + d0 = v_8(vbuf[0][i]); + + p0 ^= d0; + q0 ^= d0; + r0 ^= d0; + s0 ^= d0; + t0 ^= d0; + v_8(p[i]) = p0; v_8(q[i]) = q0; v_8(r[i]) = r0; @@ -1016,12 +1226,38 @@ void raidPP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) t = vbuf[data+4]; for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %xmm4,%xmm0"); + asm volatile("movdqa %%xmm4,%0" : "=m" (p0)); + + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.mask[0])); + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("psraw $4,%xmm5"); + asm volatile("pand %xmm7,%xmm4"); + asm volatile("pand %xmm7,%xmm5"); + + asm volatile("movdqa %0,%%xmm1" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm4,%xmm1"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm1"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm2"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][2][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][2][1][0])); + asm volatile("pshufb %xmm4,%xmm3"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm3"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[d][i])); asm volatile("movdqa %0,%%xmm6" : : "m" (p0[0])); asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); @@ -1063,7 +1299,24 @@ void raidPP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm6,%xmm3"); asm volatile("pxor %xmm7,%xmm3"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); asm volatile("movdqa %0,%%xmm6" : : "m" (p0[0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + + asm volatile("pxor %xmm5,%xmm5"); + asm volatile("pcmpgtb %xmm0,%xmm5"); + asm volatile("paddb %xmm0,%xmm0"); + asm volatile("pand %xmm7,%xmm5"); + asm volatile("pxor %xmm5,%xmm0"); + + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("pxor %xmm4,%xmm3"); + asm volatile("pxor %xmm4,%xmm6"); + asm volatile("movntdq %%xmm6,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm0,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm1,%0" : "=m" (r[i])); @@ -1102,12 +1355,37 @@ void raidPP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("movdqa %0,%%xmm15" : : "m" (gfconst16.mask[0])); for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %xmm10,%xmm0"); + asm volatile("movdqa %xmm10,%xmm1"); + + asm volatile("movdqa %xmm10,%xmm11"); + asm volatile("psraw $4,%xmm11"); + asm volatile("pand %xmm15,%xmm10"); + asm volatile("pand %xmm15,%xmm11"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm10,%xmm2"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm2"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("pshufb %xmm10,%xmm3"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm3"); + + asm volatile("movdqa %0,%%xmm4" : : "m" (gfpshufb[l][2][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][2][1][0])); + asm volatile("pshufb %xmm10,%xmm4"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm4"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[d][i])); asm volatile("pxor %xmm11,%xmm11"); @@ -1145,6 +1423,22 @@ void raidPP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm12,%xmm4"); asm volatile("pxor %xmm13,%xmm4"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[0][i])); + + asm volatile("pxor %xmm11,%xmm11"); + asm volatile("pcmpgtb %xmm1,%xmm11"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("pand %xmm14,%xmm11"); + asm volatile("pxor %xmm11,%xmm1"); + + asm volatile("pxor %xmm10,%xmm0"); + asm volatile("pxor %xmm10,%xmm1"); + asm volatile("pxor %xmm10,%xmm2"); + asm volatile("pxor %xmm10,%xmm3"); + asm volatile("pxor %xmm10,%xmm4"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm2,%0" : "=m" (r[i])); @@ -1159,9 +1453,10 @@ void raidPP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) /* * RAIDHP 8bit C implementation * - * Note that instead of a generic multiplicationt table, likely resulting in multiple cache misses, - * a precomputed table could be used. But this is only a kind of reference function, - * and we are not really interested on speed. + * Note that instead of a generic multiplicationt table, likely resulting + * in multiple cache misses, a precomputed table could be used. + * But this is only a kind of reference function, and we are not really + * interested in speed. */ void raidHP_int8(unsigned char** vbuf, unsigned data, unsigned size) { @@ -1185,8 +1480,8 @@ void raidHP_int8(unsigned char** vbuf, unsigned data, unsigned size) u = vbuf[data+5]; for(i=0;i=0;--d) { + p0 = q0 = r0 = s0 = t0 = u0 = 0; + for(d=l;d>0;--d) { d0 = v_8(vbuf[d][i]); p0 ^= d0; @@ -1196,6 +1491,17 @@ void raidHP_int8(unsigned char** vbuf, unsigned data, unsigned size) t0 ^= gfmul[d0][gfmatrix[4][d]]; u0 ^= gfmul[d0][gfmatrix[5][d]]; } + + /* first disk with all coefficients at 1 */ + d0 = v_8(vbuf[0][i]); + + p0 ^= d0; + q0 ^= d0; + r0 ^= d0; + s0 ^= d0; + t0 ^= d0; + u0 ^= d0; + v_8(p[i]) = p0; v_8(q[i]) = q0; v_8(r[i]) = r0; @@ -1235,13 +1541,44 @@ void raidHP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) u = vbuf[data+5]; for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %%xmm4,%0" : "=m" (p0)); + asm volatile("movdqa %%xmm4,%0" : "=m" (q0)); + + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.mask[0])); + asm volatile("movdqa %xmm4,%xmm5"); + asm volatile("psraw $4,%xmm5"); + asm volatile("pand %xmm7,%xmm4"); + asm volatile("pand %xmm7,%xmm5"); + + asm volatile("movdqa %0,%%xmm0" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm4,%xmm0"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm0"); + + asm volatile("movdqa %0,%%xmm1" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("pshufb %xmm4,%xmm1"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm1"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][2][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][2][1][0])); + asm volatile("pshufb %xmm4,%xmm2"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm2"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][3][0][0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfpshufb[l][3][1][0])); + asm volatile("pshufb %xmm4,%xmm3"); + asm volatile("pshufb %xmm5,%xmm7"); + asm volatile("pxor %xmm7,%xmm3"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm5" : : "m" (p0[0])); asm volatile("movdqa %0,%%xmm6" : : "m" (q0[0])); asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); @@ -1293,8 +1630,26 @@ void raidHP_ssse3(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm6,%xmm3"); asm volatile("pxor %xmm7,%xmm3"); } + + /* first disk with all coefficients at 1 */ asm volatile("movdqa %0,%%xmm5" : : "m" (p0[0])); asm volatile("movdqa %0,%%xmm6" : : "m" (q0[0])); + asm volatile("movdqa %0,%%xmm7" : : "m" (gfconst16.poly[0])); + + asm volatile("pxor %xmm4,%xmm4"); + asm volatile("pcmpgtb %xmm6,%xmm4"); + asm volatile("paddb %xmm6,%xmm6"); + asm volatile("pand %xmm7,%xmm4"); + asm volatile("pxor %xmm4,%xmm6"); + + asm volatile("movdqa %0,%%xmm4" : : "m" (vbuf[0][i])); + asm volatile("pxor %xmm4,%xmm0"); + asm volatile("pxor %xmm4,%xmm1"); + asm volatile("pxor %xmm4,%xmm2"); + asm volatile("pxor %xmm4,%xmm3"); + asm volatile("pxor %xmm4,%xmm5"); + asm volatile("pxor %xmm4,%xmm6"); + asm volatile("movntdq %%xmm5,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm6,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm0,%0" : "=m" (r[i])); @@ -1336,13 +1691,43 @@ void raidHP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("movdqa %0,%%xmm15" : : "m" (gfconst16.mask[0])); for(i=0;i=0;--d) { + /* last disk without the by two multiplication */ + asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[l][i])); + + asm volatile("movdqa %xmm10,%xmm0"); + asm volatile("movdqa %xmm10,%xmm1"); + + asm volatile("movdqa %xmm10,%xmm11"); + asm volatile("psraw $4,%xmm11"); + asm volatile("pand %xmm15,%xmm10"); + asm volatile("pand %xmm15,%xmm11"); + + asm volatile("movdqa %0,%%xmm2" : : "m" (gfpshufb[l][0][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][0][1][0])); + asm volatile("pshufb %xmm10,%xmm2"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm2"); + + asm volatile("movdqa %0,%%xmm3" : : "m" (gfpshufb[l][1][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][1][1][0])); + asm volatile("pshufb %xmm10,%xmm3"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm3"); + + asm volatile("movdqa %0,%%xmm4" : : "m" (gfpshufb[l][2][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][2][1][0])); + asm volatile("pshufb %xmm10,%xmm4"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm4"); + + asm volatile("movdqa %0,%%xmm5" : : "m" (gfpshufb[l][3][0][0])); + asm volatile("movdqa %0,%%xmm13" : : "m" (gfpshufb[l][3][1][0])); + asm volatile("pshufb %xmm10,%xmm5"); + asm volatile("pshufb %xmm11,%xmm13"); + asm volatile("pxor %xmm13,%xmm5"); + + /* intermediate disks */ + for(d=l-1;d>0;--d) { asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[d][i])); asm volatile("pxor %xmm11,%xmm11"); @@ -1387,6 +1772,23 @@ void raidHP_ssse3ext(unsigned char** vbuf, unsigned data, unsigned size) asm volatile("pxor %xmm12,%xmm5"); asm volatile("pxor %xmm13,%xmm5"); } + + /* first disk with all coefficients at 1 */ + asm volatile("movdqa %0,%%xmm10" : : "m" (vbuf[0][i])); + + asm volatile("pxor %xmm11,%xmm11"); + asm volatile("pcmpgtb %xmm1,%xmm11"); + asm volatile("paddb %xmm1,%xmm1"); + asm volatile("pand %xmm14,%xmm11"); + asm volatile("pxor %xmm11,%xmm1"); + + asm volatile("pxor %xmm10,%xmm0"); + asm volatile("pxor %xmm10,%xmm1"); + asm volatile("pxor %xmm10,%xmm2"); + asm volatile("pxor %xmm10,%xmm3"); + asm volatile("pxor %xmm10,%xmm4"); + asm volatile("pxor %xmm10,%xmm5"); + asm volatile("movntdq %%xmm0,%0" : "=m" (p[i])); asm volatile("movntdq %%xmm1,%0" : "=m" (q[i])); asm volatile("movntdq %%xmm2,%0" : "=m" (r[i])); @@ -1412,6 +1814,8 @@ static void (*raidHP_gen)(unsigned char** vbuf, unsigned data, unsigned size); void raid_gen(unsigned level, unsigned char** vbuf, unsigned data, unsigned size) { + assert(data >= RAID_DATA_MIN && data <= RAID_DATA_MAX); + switch (level) { case 1 : raid5_gen(vbuf, data, size); break; case 2 : raid6_gen(vbuf, data, size); break; diff --git a/raid.h b/raid.h index a5757ebf..2518436e 100644 --- a/raid.h +++ b/raid.h @@ -22,9 +22,16 @@ /* raid */ /** - * Max number of data disks. + * Maximum number of data disks. + * Limit of the parity generator matrix used. */ -#define RAID_DATA_LIMIT 251 +#define RAID_DATA_MAX 251 + +/** + * Minimum number of data disks. + * Limit of some optimized parity generator functions. + */ +#define RAID_DATA_MIN 2 /** * Initializes the RAID system. @@ -33,7 +40,7 @@ void raid_init(void); /** * Computes the parity. - * \param level Number of parities level to compute. Starting from 1. + * \param level Number of parities level to compute. * \param vbuf Vector of pointers to the blocks for disks and parities. * It has (::data + ::level) elements. Each element points to a buffer of ::size bytes. * \param data Number of data disks. @@ -44,8 +51,8 @@ void raid_gen(unsigned level, unsigned char** vbuf, unsigned data, unsigned size /** * Recovers failures of data disks using the specified parities. * Note that only the data blocks are recovered. The parity is destroyed. - * \param level Number of failed disks. Starting from 1. - * \param d[] Vector of indexes of the data disk to recover. Starting from 0. + * \param level Number of failed disks. + * \param d[] Vector of indexes of the data disks to recover. Starting from 0. * \param p[] Vector of indexes of the parity to use for the recovering. Starting from 0. * \param vbuf Vector of pointers to the blocks for disks and parities. * It has (::data + ::level) elements. Each element points to a buffer of ::size bytes. diff --git a/state.c b/state.c index 3494b88a..562991ac 100644 --- a/state.c +++ b/state.c @@ -143,8 +143,6 @@ static void state_config_check(struct snapraid_state* state, const char* path) /* check if all the data and parity disks are different */ if (!state->opt.skip_device) { - unsigned diskcount = 0; - for(i=state->disklist;i!=0;i=i->next) { tommy_node* j; struct snapraid_disk* disk = i->data; @@ -193,8 +191,6 @@ static void state_config_check(struct snapraid_state* state, const char* path) #endif exit(EXIT_FAILURE); } - - ++diskcount; } #ifdef _WIN32 @@ -826,8 +822,13 @@ static void state_map(struct snapraid_state* state) if (map->position + 1 > diskcount) diskcount = map->position + 1; } - if (diskcount > RAID_DATA_LIMIT) { - fprintf(stderr, "Too many datadisks. No more than %u.\n", RAID_DATA_LIMIT); + if (diskcount > RAID_DATA_MAX) { + fprintf(stderr, "Too many data disks. No more than %u.\n", RAID_DATA_MAX); + exit(EXIT_FAILURE); + } + /* some raid functions assume at least two data disk */ + if (diskcount < RAID_DATA_MIN) { + fprintf(stderr, "Too few data disks. You must define at least %u.\n", RAID_DATA_MIN); exit(EXIT_FAILURE); } }