Refactors even more and add an additional selftest.

This commit is contained in:
Andrea Mazzoleni 2013-12-31 15:46:24 +01:00
parent 8a904cbe7a
commit cbddaa108d
13 changed files with 443 additions and 258 deletions

View file

@ -25,7 +25,7 @@
/**
* Assume to always have CRC32B if running in x86
*/
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
#define HAVE_CRC32B 1
#endif

View file

@ -58,14 +58,12 @@ static __always_inline const uint8_t *table(uint8_t v)
return gfmul[v];
}
extern const uint8_t (*raid_gen)[256];
/*
* Gets the generator matrix coefficient for parity 'p' and disk 'd'.
*/
static __always_inline uint8_t A(int p, int d)
{
return raid_gen[p][d];
return gfgen[p][d];
}
/*

View file

@ -34,8 +34,6 @@ void raid_par1_int32(int nd, size_t size, void **vv)
for (i = 0; i < size; i += 8) {
p0 = v_32(v[l][i]);
p1 = v_32(v[l][i+4]);
/* accessing disks in backward order because the buffers */
/* are also in backward order */
for (d = l-1; d >= 0; --d) {
p0 ^= v_32(v[d][i]);
p1 ^= v_32(v[d][i+4]);
@ -64,8 +62,6 @@ void raid_par1_int64(int nd, size_t size, void **vv)
for (i = 0; i < size; i += 16) {
p0 = v_64(v[l][i]);
p1 = v_64(v[l][i+8]);
/* accessing disks in backward order because the buffers */
/* are also in backward order */
for (d = l-1; d >= 0; --d) {
p0 ^= v_64(v[d][i]);
p1 ^= v_64(v[d][i+8]);
@ -187,8 +183,8 @@ void raid_par3_int8(int nd, size_t size, void **vv)
d0 = v_8(v[d][i]);
p0 ^= d0;
q0 ^= gfmul[d0][gfcauchy[1][d]];
r0 ^= gfmul[d0][gfcauchy[2][d]];
q0 ^= gfmul[d0][gfgen[1][d]];
r0 ^= gfmul[d0][gfgen[2][d]];
}
/* first disk with all coefficients at 1 */
@ -236,9 +232,9 @@ void raid_par4_int8(int nd, size_t size, void **vv)
d0 = v_8(v[d][i]);
p0 ^= d0;
q0 ^= gfmul[d0][gfcauchy[1][d]];
r0 ^= gfmul[d0][gfcauchy[2][d]];
s0 ^= gfmul[d0][gfcauchy[3][d]];
q0 ^= gfmul[d0][gfgen[1][d]];
r0 ^= gfmul[d0][gfgen[2][d]];
s0 ^= gfmul[d0][gfgen[3][d]];
}
/* first disk with all coefficients at 1 */
@ -290,10 +286,10 @@ void raid_par5_int8(int nd, size_t size, void **vv)
d0 = v_8(v[d][i]);
p0 ^= d0;
q0 ^= gfmul[d0][gfcauchy[1][d]];
r0 ^= gfmul[d0][gfcauchy[2][d]];
s0 ^= gfmul[d0][gfcauchy[3][d]];
t0 ^= gfmul[d0][gfcauchy[4][d]];
q0 ^= gfmul[d0][gfgen[1][d]];
r0 ^= gfmul[d0][gfgen[2][d]];
s0 ^= gfmul[d0][gfgen[3][d]];
t0 ^= gfmul[d0][gfgen[4][d]];
}
/* first disk with all coefficients at 1 */
@ -349,11 +345,11 @@ void raid_par6_int8(int nd, size_t size, void **vv)
d0 = v_8(v[d][i]);
p0 ^= d0;
q0 ^= gfmul[d0][gfcauchy[1][d]];
r0 ^= gfmul[d0][gfcauchy[2][d]];
s0 ^= gfmul[d0][gfcauchy[3][d]];
t0 ^= gfmul[d0][gfcauchy[4][d]];
u0 ^= gfmul[d0][gfcauchy[5][d]];
q0 ^= gfmul[d0][gfgen[1][d]];
r0 ^= gfmul[d0][gfgen[2][d]];
s0 ^= gfmul[d0][gfgen[3][d]];
t0 ^= gfmul[d0][gfgen[4][d]];
u0 ^= gfmul[d0][gfgen[5][d]];
}
/* first disk with all coefficients at 1 */

View file

@ -31,6 +31,8 @@
*
* These are intented to provide access for testing.
*/
int raid_selftest(void);
void raid_par_ref(int nd, int np, size_t size, void **vv);
void raid_invert(uint8_t *M, uint8_t *V, int n);
void raid_delta_gen(int nr, const int *id, const int *ip, int nd, size_t size, void **v);
void raid_rec1_par1(const int *id, int nd, size_t size, void **v);
@ -99,14 +101,15 @@ extern const uint8_t raid_gfvandermonde[3][256] __aligned(256);
extern const uint8_t raid_gfcauchy[6][256] __aligned(256);
extern const uint8_t raid_gfcauchypshufb[251][4][2][16] __aligned(256);
extern const uint8_t raid_gfmulpshufb[256][2][16] __aligned(256);
extern const uint8_t (*raid_gfgen)[256];
#define gfmul raid_gfmul
#define gfexp raid_gfexp
#define gfinv raid_gfinv
#define gfvandermonde raid_gfvandermonde
#define gfcauchy raid_gfcauchy
#define gfcauchypshufb raid_gfcauchypshufb
#define gfgenpshufb raid_gfcauchypshufb
#define gfmulpshufb raid_gfmulpshufb
#define gfgen raid_gfgen
/*
* Assembler blocks.
*/

View file

@ -13,6 +13,7 @@
*/
#include "internal.h"
#include "memory.h"
#include "cpu.h"
void raid_init(void)
@ -81,6 +82,183 @@ void raid_init(void)
raid_mode(RAID_MODE_CAUCHY);
}
/*
* Refence parity computation.
*/
void raid_par_ref(int nd, int np, size_t size, void **vv)
{
uint8_t **v = (uint8_t **)vv;
size_t i;
for (i = 0; i < size; ++i) {
uint8_t p[RAID_PARITY_MAX];
int j, d;
for (j = 0; j < np; ++j)
p[j] = 0;
for (d = 0; d < nd; ++d) {
uint8_t b = v[d][i];
for (j = 0; j < np; ++j)
p[j] ^= gfmul[b][gfgen[j][d]];
}
for (j = 0; j < np; ++j)
v[nd + j][i] = p[j];
}
}
/**
* Number of data disks to test.
*/
#define TEST_DATA_MAX 8
/*
* Parity generation test.
*/
static int raid_test_par(int nd, int np, size_t size, void **v, void **ref)
{
int i;
void *t[TEST_DATA_MAX + RAID_PARITY_MAX];
/* setup data */
for (i = 0; i < nd; ++i)
t[i] = ref[i];
/* setup parity */
for (i = 0; i < np; ++i)
t[nd+i] = v[nd+i];
raid_par(nd, np, size, t);
/* compare parity */
for (i = 0; i < np; ++i)
if (memcmp(t[nd+i], ref[nd+i], size) != 0)
return -1;
return 0;
}
/*
* Recovering test.
*/
static int raid_test_rec(int nrd, int *id, int nrp, int *ip, int nd, int np, size_t size, void **v, void **ref)
{
int i, j;
void *t[TEST_DATA_MAX + RAID_PARITY_MAX];
/* setup data */
for (i = 0, j = 0; i < nd; ++i) {
if (j < nrd && id[j] == i) {
t[i] = v[i];
++j;
} else {
t[i] = ref[i];
}
}
/* setup parity */
for (i = 0, j = 0; i < np; ++i) {
if (j < nrp && ip[j] == i) {
t[nd+i] = v[nd+i];
++j;
} else {
t[nd+i] = ref[nd+i];
}
}
raid_rec(nrd, id, nrp, ip, nd, np, size, t);
/* compare all data and parity */
for (i = 0; i < nd+np; ++i)
if (t[i] != ref[i] && memcmp(t[i], ref[i], size) != 0)
return -1;
return 0;
}
/*
* Basic functionality self test.
*/
int raid_selftest(void)
{
const int nd = TEST_DATA_MAX;
const int nv = nd + RAID_PARITY_MAX * 2 + 1;
const size_t size = 4096;
void *v_alloc;
void **v;
void *ref[nd + RAID_PARITY_MAX];
int id[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
int i, np;
/* ensure to have enough space for data */
BUG_ON(TEST_DATA_MAX * size > 65536);
v = raid_malloc_vector(nd, nv, size, &v_alloc);
if (!v)
return -1;
memset(v[nv-1], 0, size);
raid_zero(v[nv-1]);
/* use the multiplication table as data */
for (i = 0; i < nd; ++i)
ref[i] = ((uint8_t *)gfmul) + size * i;
/* setup reference parity */
for (i = 0; i < RAID_PARITY_MAX; ++i)
ref[nd+i] = v[nd+RAID_PARITY_MAX+i];
/* compute reference parity */
raid_par_ref(nd, RAID_PARITY_MAX, size, ref);
/* test for each parity level */
for (np = 1; np <= RAID_PARITY_MAX; ++np) {
int r;
/* test parity generation */
r = raid_test_par(nd, np, size, v, ref);
if (r != 0)
return r;
/* test recovering with full broken data disks */
for (i = 0; i < np; ++i)
id[i] = nd - np + i;
r = raid_test_rec(np, id, 0, ip, nd, np, size, v, ref);
if (r != 0)
return r;
/* test recovering with half broken data and ending parity */
for (i = 0; i < np / 2; ++i)
id[i] = i;
for (i = 0; i < (np + 1) / 2; ++i)
ip[i] = np - np / 2 + i;
r = raid_test_rec(np / 2, id, np / 2, ip, nd, np, size, v, ref);
if (r != 0)
return r;
/* test recovering with half broken data and leading parity */
for (i = 0; i < np / 2; ++i)
id[i] = i;
for (i = 0; i < (np + 1) / 2; ++i)
ip[i] = i;
r = raid_test_rec(np / 2, id, np / 2, ip, nd, np, size, v, ref);
if (r != 0)
return r;
}
free(v_alloc);
return 0;
}
static struct raid_func {
const char *name;
void *p;

View file

@ -171,16 +171,16 @@
/**
* Generator matrix currently used.
*/
const uint8_t (*raid_gen)[256];
const uint8_t (*raid_gfgen)[256];
void raid_mode(int mode)
{
if (mode == RAID_MODE_VANDERMONDE) {
raid_par_ptr[2] = raid_parz_ptr;
raid_gen = gfvandermonde;
raid_gfgen = gfvandermonde;
} else {
raid_par_ptr[2] = raid_par3_ptr;
raid_gen = gfcauchy;
raid_gfgen = gfcauchy;
}
}
@ -412,7 +412,7 @@ void raid_rec(int nrd, const int *id, int nrp, int *ip, int nd, int np, size_t s
/* setup the vector of parities to use */
for (i = 0, j = 0, k = 0; i < np; ++i) {
if (ip[j] == i) {
if (j < nrp && ip[j] == i) {
/* this parity has to be recovered */
++j;
} else {
@ -451,7 +451,7 @@ void raid_rec_dataonly(int nr, const int *id, const int *ip, int nd, size_t size
for (i = 0, j = 0; i < np; ++i) {
p[i] = v[nd+i];
if (ip[j] == i) {
if (j < nr && ip[j] == i) {
/* this parity is used for recovering */
++j;
} else {

View file

@ -21,7 +21,7 @@
* It requires SSSE3 to get good performance with triple or more
* parities.
*
* This is the default mode used by SnapRAID.
* This is the default mode set after calling raid_init().
*/
#define RAID_MODE_CAUCHY 0
@ -49,6 +49,13 @@
*/
void raid_init(void);
/**
* Runs a basic functionality self test.
*
* It returns 0 on success.
*/
int raid_selftest(void);
/**
* Sets the mode to use. One of RAID_MODE_*.
*

View file

@ -105,23 +105,22 @@ int raid_test_sort(void)
int raid_test_rec(int mode, int nd, size_t size)
{
void *buffer_alloc;
void **buffer;
void *v_alloc;
void **v;
void **data;
void **parity;
void **test;
void *data_save[RAID_PARITY_MAX];
void *parity_save[RAID_PARITY_MAX];
void *zero;
void *waste;
int buffermax;
int nv;
int id[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
int i;
int j;
int nr;
void (*map[RAID_PARITY_MAX][4])(int nr, const int *id, const int *ip, int nd, size_t size, void **vbuf);
int mac[RAID_PARITY_MAX];
void (*f[RAID_PARITY_MAX][4])(int nr, const int *id, const int *ip, int nd, size_t size, void **vbuf);
int nf[RAID_PARITY_MAX];
int np;
raid_mode(mode);
@ -130,56 +129,55 @@ int raid_test_rec(int mode, int nd, size_t size)
else
np = 3;
buffermax = nd + np * 2 + 2;
nv = nd + np * 2 + 2;
buffer = raid_malloc_vector(nd, buffermax, size, &buffer_alloc);
if (!buffer)
v = raid_malloc_vector(nd, nv, size, &v_alloc);
if (!v)
return -1;
data = buffer;
parity = buffer + nd;
test = buffer + nd + np;
data = v;
parity = v + nd;
test = v + nd + np;
for (i = 0; i < np; ++i)
parity_save[i] = parity[i];
zero = buffer[buffermax-2];
memset(zero, 0, size);
raid_zero(zero);
memset(v[nv-2], 0, size);
raid_zero(v[nv-2]);
waste = buffer[buffermax-1];
waste = v[nv-1];
/* fill data disk with random */
raid_mrand_vector(buffer, nd, size);
raid_mrand_vector(v, nd, size);
/* setup recov functions */
for (i = 0; i < np; ++i) {
mac[i] = 0;
nf[i] = 0;
if (i == 0) {
map[i][mac[i]++] = raid_rec1_int8;
f[i][nf[i]++] = raid_rec1_int8;
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3())
map[i][mac[i]++] = raid_rec1_ssse3;
f[i][nf[i]++] = raid_rec1_ssse3;
#endif
} else if (i == 1) {
map[i][mac[i]++] = raid_rec2_int8;
f[i][nf[i]++] = raid_rec2_int8;
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3())
map[i][mac[i]++] = raid_rec2_ssse3;
f[i][nf[i]++] = raid_rec2_ssse3;
#endif
} else {
map[i][mac[i]++] = raid_recX_int8;
f[i][nf[i]++] = raid_recX_int8;
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3())
map[i][mac[i]++] = raid_recX_ssse3;
f[i][nf[i]++] = raid_recX_ssse3;
#endif
}
}
/* compute the parity */
raid_par(nd, np, size, buffer);
raid_par_ref(nd, np, size, v);
/* set all the parity to the waste buffer */
/* set all the parity to the waste v */
for (i = 0; i < np; ++i)
parity[i] = waste;
@ -192,7 +190,7 @@ int raid_test_rec(int mode, int nd, size_t size)
combination_first(nr, np, ip);
do {
/* for each recover function */
for (j = 0; j < mac[nr-1]; ++j) {
for (j = 0; j < nf[nr-1]; ++j) {
/* set */
for (i = 0; i < nr; ++i) {
/* remove the missing data */
@ -203,7 +201,7 @@ int raid_test_rec(int mode, int nd, size_t size)
}
/* recover */
map[nr-1][j](nr, id, ip, nd, size, buffer);
f[nr-1][j](nr, id, ip, nd, size, v);
/* check */
for (i = 0; i < nr; ++i)
@ -222,20 +220,20 @@ int raid_test_rec(int mode, int nd, size_t size)
} while (combination_next(nr, nd, id));
}
free(buffer_alloc);
free(buffer);
free(v_alloc);
free(v);
return 0;
}
int raid_test_par(int mode, int nd, size_t size)
{
void *buffer_alloc;
void **buffer;
int buffermax;
void *v_alloc;
void **v;
int nv;
int i, j;
void (*map[64])(int nd, size_t size, void **vbuf);
int mac;
void (*f[64])(int nd, size_t size, void **vbuf);
int nf;
int np;
raid_mode(mode);
@ -244,87 +242,87 @@ int raid_test_par(int mode, int nd, size_t size)
else
np = 3;
buffermax = nd + np * 2;
nv = nd + np * 2;
buffer = raid_malloc_vector(nd, buffermax, size, &buffer_alloc);
if (!buffer)
v = raid_malloc_vector(nd, nv, size, &v_alloc);
if (!v)
return -1;
/* fill with random */
raid_mrand_vector(buffer, buffermax, size);
raid_mrand_vector(v, nv, size);
/* compute the parity */
raid_par(nd, np, size, buffer);
raid_par_ref(nd, np, size, v);
/* copy in back buffers */
for (i = 0; i < np; ++i)
memcpy(buffer[nd + np + i], buffer[nd + i], size);
memcpy(v[nd + np + i], v[nd + i], size);
/* load all the available functions */
mac = 0;
nf = 0;
map[mac++] = raid_par1_int32;
map[mac++] = raid_par1_int64;
map[mac++] = raid_par2_int32;
map[mac++] = raid_par2_int64;
f[nf++] = raid_par1_int32;
f[nf++] = raid_par1_int64;
f[nf++] = raid_par2_int32;
f[nf++] = raid_par2_int64;
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
map[mac++] = raid_par1_sse2;
map[mac++] = raid_par2_sse2;
f[nf++] = raid_par1_sse2;
f[nf++] = raid_par2_sse2;
#ifdef CONFIG_X86_64
map[mac++] = raid_par2_sse2ext;
f[nf++] = raid_par2_sse2ext;
#endif
}
#endif
if (mode == RAID_MODE_CAUCHY) {
map[mac++] = raid_par3_int8;
map[mac++] = raid_par4_int8;
map[mac++] = raid_par5_int8;
map[mac++] = raid_par6_int8;
f[nf++] = raid_par3_int8;
f[nf++] = raid_par4_int8;
f[nf++] = raid_par5_int8;
f[nf++] = raid_par6_int8;
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
map[mac++] = raid_par3_ssse3;
map[mac++] = raid_par4_ssse3;
map[mac++] = raid_par5_ssse3;
map[mac++] = raid_par6_ssse3;
f[nf++] = raid_par3_ssse3;
f[nf++] = raid_par4_ssse3;
f[nf++] = raid_par5_ssse3;
f[nf++] = raid_par6_ssse3;
#ifdef CONFIG_X86_64
map[mac++] = raid_par3_ssse3ext;
map[mac++] = raid_par4_ssse3ext;
map[mac++] = raid_par5_ssse3ext;
map[mac++] = raid_par6_ssse3ext;
f[nf++] = raid_par3_ssse3ext;
f[nf++] = raid_par4_ssse3ext;
f[nf++] = raid_par5_ssse3ext;
f[nf++] = raid_par6_ssse3ext;
#endif
}
#endif
} else {
map[mac++] = raid_parz_int32;
map[mac++] = raid_parz_int64;
f[nf++] = raid_parz_int32;
f[nf++] = raid_parz_int64;
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
map[mac++] = raid_parz_sse2;
f[nf++] = raid_parz_sse2;
#ifdef CONFIG_X86_64
map[mac++] = raid_parz_sse2ext;
f[nf++] = raid_parz_sse2ext;
#endif
}
#endif
}
/* check all the functions */
for (j = 0; j < mac; ++j) {
for (j = 0; j < nf; ++j) {
/* compute parity */
map[j](nd, size, buffer);
f[j](nd, size, v);
/* check it */
for (i = 0; i < np; ++i)
if (memcmp(buffer[nd + np + i], buffer[nd + i], size) != 0)
if (memcmp(v[nd + np + i], v[nd + i], size) != 0)
return -1;
}
free(buffer_alloc);
free(buffer);
free(v_alloc);
free(v);
return 0;
}

View file

@ -41,8 +41,6 @@ void raid_par1_sse2(int nd, size_t size, void **vv)
asm volatile("movdqa %0,%%xmm1" : : "m" (v[l][i+16]));
asm volatile("movdqa %0,%%xmm2" : : "m" (v[l][i+32]));
asm volatile("movdqa %0,%%xmm3" : : "m" (v[l][i+48]));
/* accessing disks in backward order because the buffers */
/* are also in backward order */
for (d = l-1; d >= 0; --d) {
asm volatile("movdqa %0,%%xmm4" : : "m" (v[d][i]));
asm volatile("movdqa %0,%%xmm5" : : "m" (v[d][i+16]));
@ -250,8 +248,8 @@ void raid_par3_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[l][0][1][0]));
asm volatile("pshufb %xmm4,%xmm2");
asm volatile("pshufb %xmm5,%xmm6");
asm volatile("pxor %xmm6,%xmm2");
@ -274,10 +272,10 @@ void raid_par3_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pxor %xmm6,%xmm2");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm5,%xmm6");
asm volatile("pxor %xmm6,%xmm2");
}
@ -356,8 +354,8 @@ void raid_par3_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm11,%xmm5");
asm volatile("pand %xmm11,%xmm13");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
asm volatile("movdqa %xmm2,%xmm10");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm2");
@ -397,8 +395,8 @@ void raid_par3_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm11,%xmm5");
asm volatile("pand %xmm11,%xmm13");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("movdqa %xmm6,%xmm14");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm6");
@ -488,14 +486,14 @@ void raid_par4_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
asm volatile("pshufb %xmm4,%xmm3");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm7,%xmm3");
@ -521,15 +519,15 @@ void raid_par4_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm2");
asm volatile("pxor %xmm7,%xmm2");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm3");
@ -613,8 +611,8 @@ void raid_par4_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm5");
asm volatile("pand %xmm15,%xmm13");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][0][1][0]));
asm volatile("movdqa %xmm2,%xmm10");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm2");
@ -624,8 +622,8 @@ void raid_par4_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pxor %xmm7,%xmm2");
asm volatile("pxor %xmm15,%xmm10");
asm volatile("movdqa %0,%%xmm3" : : "m" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][1][1][0]));
asm volatile("movdqa %xmm3,%xmm11");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm3");
@ -667,8 +665,8 @@ void raid_par4_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm5");
asm volatile("pand %xmm15,%xmm13");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("movdqa %xmm6,%xmm14");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm6");
@ -680,8 +678,8 @@ void raid_par4_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pxor %xmm7,%xmm2");
asm volatile("pxor %xmm15,%xmm10");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("movdqa %xmm6,%xmm14");
asm volatile("movdqa %xmm7,%xmm15");
asm volatile("pshufb %xmm4,%xmm6");
@ -785,20 +783,20 @@ void raid_par5_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm1" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][2][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][2][1][0]));
asm volatile("pshufb %xmm4,%xmm3");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm7,%xmm3");
@ -825,22 +823,22 @@ void raid_par5_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm1");
asm volatile("pxor %xmm7,%xmm1");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm2");
asm volatile("pxor %xmm7,%xmm2");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][2][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm3");
@ -924,20 +922,20 @@ void raid_par5_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm10");
asm volatile("pand %xmm15,%xmm11");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][2][1][0]));
asm volatile("movdqa %0,%%xmm4" : : "m" (gfgenpshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][2][1][0]));
asm volatile("pshufb %xmm10,%xmm4");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm13,%xmm4");
@ -960,22 +958,22 @@ void raid_par5_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm10");
asm volatile("pand %xmm15,%xmm11");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm2");
asm volatile("pxor %xmm13,%xmm2");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm3");
asm volatile("pxor %xmm13,%xmm3");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][2][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][2][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm4");
@ -1061,26 +1059,26 @@ void raid_par6_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm0" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm0" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm1" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][2][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][3][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[l][3][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][3][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[l][3][1][0]));
asm volatile("pshufb %xmm4,%xmm3");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm7,%xmm3");
@ -1110,29 +1108,29 @@ void raid_par6_ssse3(int nd, size_t size, void **vv)
asm volatile("pand %xmm7,%xmm4");
asm volatile("pand %xmm7,%xmm5");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm0");
asm volatile("pxor %xmm7,%xmm0");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm1");
asm volatile("pxor %xmm7,%xmm1");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][2][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][2][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm2");
asm volatile("pxor %xmm7,%xmm2");
asm volatile("movdqa %0,%%xmm6" : : "m" (gfcauchypshufb[d][3][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfcauchypshufb[d][3][1][0]));
asm volatile("movdqa %0,%%xmm6" : : "m" (gfgenpshufb[d][3][0][0]));
asm volatile("movdqa %0,%%xmm7" : : "m" (gfgenpshufb[d][3][1][0]));
asm volatile("pshufb %xmm4,%xmm6");
asm volatile("pshufb %xmm5,%xmm7");
asm volatile("pxor %xmm6,%xmm3");
@ -1221,26 +1219,26 @@ void raid_par6_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm10");
asm volatile("pand %xmm15,%xmm11");
asm volatile("movdqa %0,%%xmm2" : : "m" (gfcauchypshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][0][1][0]));
asm volatile("movdqa %0,%%xmm2" : : "m" (gfgenpshufb[l][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][1][1][0]));
asm volatile("movdqa %0,%%xmm3" : : "m" (gfgenpshufb[l][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][2][1][0]));
asm volatile("movdqa %0,%%xmm4" : : "m" (gfgenpshufb[l][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[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" (gfcauchypshufb[l][3][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[l][3][1][0]));
asm volatile("movdqa %0,%%xmm5" : : "m" (gfgenpshufb[l][3][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[l][3][1][0]));
asm volatile("pshufb %xmm10,%xmm5");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm13,%xmm5");
@ -1263,29 +1261,29 @@ void raid_par6_ssse3ext(int nd, size_t size, void **vv)
asm volatile("pand %xmm15,%xmm10");
asm volatile("pand %xmm15,%xmm11");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][0][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][0][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][0][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm2");
asm volatile("pxor %xmm13,%xmm2");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][1][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][1][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][1][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm3");
asm volatile("pxor %xmm13,%xmm3");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][2][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][2][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][2][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm4");
asm volatile("pxor %xmm13,%xmm4");
asm volatile("movdqa %0,%%xmm12" : : "m" (gfcauchypshufb[d][3][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfcauchypshufb[d][3][1][0]));
asm volatile("movdqa %0,%%xmm12" : : "m" (gfgenpshufb[d][3][0][0]));
asm volatile("movdqa %0,%%xmm13" : : "m" (gfgenpshufb[d][3][1][0]));
asm volatile("pshufb %xmm10,%xmm12");
asm volatile("pshufb %xmm11,%xmm13");
asm volatile("pxor %xmm12,%xmm5");

View file

@ -162,6 +162,10 @@ void selftest(void)
test_hash();
test_crc32c();
if (raid_selftest() != 0) {
fprintf(stderr, "Failed SELF test\n");
exit(EXIT_FAILURE);
}
if (raid_test_sort() != 0) {
fprintf(stderr, "Failed SORT test\n");
exit(EXIT_FAILURE);

147
speed.c
View file

@ -24,6 +24,11 @@
#include "raid/internal.h"
#include "state.h"
/*
* Size of the blocks to test.
*/
#define TEST_SIZE (256*1024)
/**
* Differential us of two timeval.
*/
@ -44,7 +49,7 @@ static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
count = 0; \
gettimeofday(&start, 0); \
do { \
for(i=0;i<delta;++i)
for (i = 0; i < delta; ++i)
/**
* Stop time measurement.
@ -65,37 +70,35 @@ void speed(void)
int i, j;
unsigned char digest[HASH_SIZE];
unsigned char seed[HASH_SIZE];
int id[LEV_MAX];
int ip[LEV_MAX];
int id[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
int count;
int delta = 10;
int size = 256 * 1024;
int size = TEST_SIZE;
int nd = 8;
int buffermax;
void* v_alloc;
void** v;
void* zero;
int nv;
void *v_alloc;
void **v;
/* we need disk + 1 for each parity buffers + 1 zero v */
buffermax = nd + LEV_MAX + 1;
nv = nd + RAID_PARITY_MAX + 1;
v = malloc_nofail_vector_align(nd, buffermax, size, &v_alloc);
v = malloc_nofail_vector_align(nd, nv, size, &v_alloc);
/* initialize disks with fixed data */
for(i=0;i<nd;++i)
for (i = 0; i < nd; ++i)
memset(v[i], i, size);
/* zero v */
zero = v[nd+LEV_MAX];
memset(zero, 0, size);
raid_zero(zero);
memset(v[nd+RAID_PARITY_MAX], 0, size);
raid_zero(v[nd+RAID_PARITY_MAX]);
/* hash seed */
for(i=0;i<HASH_SIZE;++i)
for (i = 0; i < HASH_SIZE; ++i)
seed[i] = i;
/* basic disks and parity mapping */
for(i=0;i<LEV_MAX;++i) {
for (i = 0; i < RAID_PARITY_MAX; ++i) {
id[i] = i;
ip[i] = i;
}
@ -106,7 +109,7 @@ void speed(void)
printf("Compiler gcc " __VERSION__ "\n");
#endif
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
{
char vendor[CPU_VENDOR_MAX];
unsigned family;
@ -129,9 +132,9 @@ void speed(void)
printf("CPU is not a x86/x64\n");
#endif
#if WORDS_BIGENDIAN
printf("Memory is big-endian %d-bit\n", (int)sizeof(void*) * 8);
printf("Memory is big-endian %d-bit\n", (int)sizeof(void *) * 8);
#else
printf("Memory is little-endian %d-bit\n", (int)sizeof(void*) * 8);
printf("Memory is little-endian %d-bit\n", (int)sizeof(void *) * 8);
#endif
#if HAVE_FUTIMENS
@ -156,7 +159,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
memset(v[j], j, size);
} SPEED_STOP
@ -171,7 +174,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
crc32c_gen(0, v[j], size);
} SPEED_STOP
@ -184,7 +187,7 @@ void speed(void)
#if HAVE_CRC32B
if (raid_cpu_has_sse42()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
crc32c_x86(0, v[j], size);
} SPEED_STOP
@ -204,13 +207,13 @@ void speed(void)
printf("\n");
printf("%8s", "hash");
#if defined(__i386__) || defined(__x86_64__)
if (sizeof(void*) == 4 && !raid_cpu_has_slowmult())
#ifdef CONFIG_X86
if (sizeof(void *) == 4 && !raid_cpu_has_slowmult())
printf("%8s", "murmur3");
else
printf("%8s", "spooky2");
#else
if (sizeof(void*) == 4)
if (sizeof(void *) == 4)
printf("%8s", "murmur3");
else
printf("%8s", "spooky2");
@ -218,7 +221,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
memhash(HASH_MURMUR3, seed, digest, v[j], size);
} SPEED_STOP
@ -226,7 +229,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
memhash(HASH_SPOOKY2, seed, digest, v[j], size);
} SPEED_STOP
@ -241,13 +244,13 @@ void speed(void)
printf("%8s", "int8");
printf("%8s", "int32");
printf("%8s", "int64");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
printf("%8s", "sse2");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "sse2e");
#endif
printf("%8s", "ssse3");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "ssse3e");
#endif
#endif
@ -274,7 +277,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
SPEED_START {
raid_par1_sse2(nd, size, v);
@ -307,7 +310,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
SPEED_START {
raid_par2_sse2(nd, size, v);
@ -316,7 +319,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_par2_sse2ext(nd, size, v);
} SPEED_STOP
@ -349,7 +352,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
SPEED_START {
raid_parz_sse2(nd, size, v);
@ -358,7 +361,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_parz_sse2ext(nd, size, v);
} SPEED_STOP
@ -385,17 +388,17 @@ void speed(void)
printf("%8s", "");
printf("%8s", "");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
printf("%8s", "");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "");
#endif
}
#endif
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
raid_par3_ssse3(nd, size, v);
@ -404,7 +407,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_par3_ssse3ext(nd, size, v);
} SPEED_STOP
@ -431,17 +434,17 @@ void speed(void)
printf("%8s", "");
printf("%8s", "");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
printf("%8s", "");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "");
#endif
}
#endif
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
raid_par4_ssse3(nd, size, v);
@ -450,7 +453,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_par4_ssse3ext(nd, size, v);
} SPEED_STOP
@ -461,7 +464,7 @@ void speed(void)
}
#endif
printf("\n");
/* PAR5 */
printf("%8s", "par5");
printf("%8s", raid_par5_tag());
@ -477,17 +480,17 @@ void speed(void)
printf("%8s", "");
printf("%8s", "");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
printf("%8s", "");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "");
#endif
}
#endif
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
raid_par5_ssse3(nd, size, v);
@ -496,7 +499,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_par5_ssse3ext(nd, size, v);
} SPEED_STOP
@ -523,17 +526,17 @@ void speed(void)
printf("%8s", "");
printf("%8s", "");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_sse2()) {
printf("%8s", "");
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
printf("%8s", "");
#endif
}
#endif
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
raid_par6_ssse3(nd, size, v);
@ -542,7 +545,7 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
SPEED_START {
raid_par6_ssse3ext(nd, size, v);
} SPEED_STOP
@ -560,7 +563,7 @@ void speed(void)
printf("%8s", "");
printf("%8s", "best");
printf("%8s", "int8");
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
printf("%8s", "ssse3");
#endif
printf("\n");
@ -570,7 +573,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
/* +1 to avoid PAR1 optimized case */
raid_rec1_int8(1, id, ip + 1, nd, size, v);
} SPEED_STOP
@ -578,10 +581,10 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
/* +1 to avoid PAR1 optimized case */
raid_rec1_ssse3(1, id, ip + 1, nd, size, v);
} SPEED_STOP
@ -596,7 +599,7 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
/* +1 to avoid PAR2 optimized case */
raid_rec2_int8(2, id, ip + 1, nd, size, v);
} SPEED_STOP
@ -604,10 +607,10 @@ void speed(void)
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
/* +1 to avoid PAR2 optimized case */
raid_rec2_ssse3(2, id, ip + 1, nd, size, v);
} SPEED_STOP
@ -622,17 +625,17 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_int8(3, id, ip, nd, size, v);
} SPEED_STOP
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_ssse3(3, id, ip, nd, size, v);
} SPEED_STOP
@ -646,17 +649,17 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_int8(4, id, ip, nd, size, v);
} SPEED_STOP
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_ssse3(4, id, ip, nd, size, v);
} SPEED_STOP
@ -670,17 +673,17 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_int8(5, id, ip, nd, size, v);
} SPEED_STOP
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_ssse3(5, id, ip, nd, size, v);
} SPEED_STOP
@ -694,17 +697,17 @@ void speed(void)
fflush(stdout);
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_int8(6, id, ip, nd, size, v);
} SPEED_STOP
printf("%8"PRIu64, ds / dt);
fflush(stdout);
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (raid_cpu_has_ssse3()) {
SPEED_START {
for(j=0;j<nd;++j)
for (j = 0; j < nd; ++j)
raid_recX_ssse3(6, id, ip, nd, size, v);
} SPEED_STOP

View file

@ -282,7 +282,7 @@ static void state_config_check(struct snapraid_state* state, const char* path, t
}
/* check for speed */
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (!raid_cpu_has_ssse3())
#endif
if (state->raid_mode == RAID_MODE_CAUCHY) {
@ -703,7 +703,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
} else if (state->opt.force_spooky2) {
state->besthash = HASH_SPOOKY2;
} else {
#if defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_X86
if (sizeof(void*) == 4 && !raid_cpu_has_slowmult())
state->besthash = HASH_MURMUR3;
else

4
util.c
View file

@ -1094,13 +1094,13 @@ uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
{
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
uint64_t crc64;
#endif
crc ^= CRC_IV;
#if defined(__x86_64__)
#ifdef CONFIG_X86_64
crc64 = crc;
while (size >= 8) {
asm volatile ("crc32q %1, %0\n" : "+r" (crc64) : "rm" (*(uint64_t*)ptr));