[sheepdog] [PATCH v1 3/3] sheep: add funciton to compute ec by isa-l
Robin Dong
robin.k.dong at gmail.com
Fri Sep 19 08:01:15 CEST 2014
From: Robin Dong <sanbai at taobao.com>
Add new functions such as isa_decode_buffer().
It will choose correct funciton to compute ec when running.
Signed-off-by: Robin Dong <sanbai at taobao.com>
---
include/fec.h | 27 ++++++++++++++++++++++++---
lib/fec.c | 38 +++++++++++++++++++++++++++++++++++++-
2 files changed, 61 insertions(+), 4 deletions(-)
diff --git a/include/fec.h b/include/fec.h
index b3c6e55..1ae32e4 100644
--- a/include/fec.h
+++ b/include/fec.h
@@ -64,11 +64,13 @@
#include "util.h"
#include "sheepdog_proto.h"
+#include "../lib/isa-l/include/erasure_code.h"
struct fec {
unsigned long magic;
unsigned short d, dp; /* parameters of the code */
uint8_t *enc_matrix;
+ unsigned char *ec_tbl; /* for isa-l */
};
void init_fec(void);
@@ -93,6 +95,14 @@ void fec_encode(const struct fec *code,
const int *const block_nums,
size_t num_block_nums, size_t sz);
+void fec_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
+ char *buf, int idx);
+
+/* for isa-l */
+
+void isa_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
+ char *buf, int idx);
+
/*
* @param inpkts an array of packets (size k); If a primary block, i, is present
* then it must be at index i. Secondary blocks can appear anywhere.
@@ -167,7 +177,12 @@ static inline void ec_encode(struct fec *ctx, const uint8_t *ds[],
for (int i = 0; i < p; i++)
pidx[i] = ctx->d + i;
- fec_encode(ctx, ds, ps, pidx, p, SD_EC_DATA_STRIPE_SIZE / ctx->d);
+ if (cpu_has_ssse3)
+ ec_encode_data_sse(SD_EC_DATA_STRIPE_SIZE / ctx->d, ctx->d, p,
+ ctx->ec_tbl, (unsigned char **)ds, ps);
+ else
+ fec_encode(ctx, ds, ps, pidx, p, SD_EC_DATA_STRIPE_SIZE /
+ ctx->d);
}
/*
@@ -189,6 +204,12 @@ static inline void ec_destroy(struct fec *ctx)
fec_free(ctx);
}
-void ec_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
- char *buf, int idx);
+static inline void ec_decode_buffer(struct fec *ctx, uint8_t *input[],
+ const int in_idx[], char *buf, int idx)
+{
+ if (cpu_has_ssse3)
+ isa_decode_buffer(ctx, input, in_idx, buf, idx);
+ else
+ fec_decode_buffer(ctx, input, in_idx, buf, idx);
+}
#endif
diff --git a/lib/fec.c b/lib/fec.c
index 520d0d2..c4e7a6f 100644
--- a/lib/fec.c
+++ b/lib/fec.c
@@ -454,6 +454,8 @@ void fec_free(struct fec *p)
assert(p != NULL && p->magic == (((FEC_MAGIC ^ p->d) ^ p->dp) ^
(unsigned long) (p->enc_matrix)));
free(p->enc_matrix);
+ if (cpu_has_ssse3)
+ free(p->ec_tbl);
free(p);
}
@@ -494,6 +496,12 @@ struct fec *fec_new(unsigned short d, unsigned short dp)
*p = 1;
free(tmp_m);
+ if (cpu_has_ssse3) {
+ retval->ec_tbl = xmalloc(dp * d * 32);
+ ec_init_tables(d, dp - d, retval->enc_matrix + (d * d),
+ retval->ec_tbl);
+ } else
+ retval->ec_tbl = NULL;
return retval;
}
@@ -687,7 +695,7 @@ out:
memcpy(output, dp[idx], strip_size);
}
-void ec_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
+void fec_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
char *buf, int idx)
{
int i, j, d = ctx->d;
@@ -703,3 +711,31 @@ void ec_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
memcpy(buf + strip_size * i, out, strip_size);
}
}
+
+void isa_decode_buffer(struct fec *ctx, uint8_t *input[], const int in_idx[],
+ char *buf, int idx)
+{
+ int ed = ctx->d, edp = ctx->dp, len = SD_DATA_OBJ_SIZE / ed, i;
+ unsigned char ec_tbl[ed * edp * 32];
+ unsigned char bm[ed * ed];
+ unsigned char cm[ed];
+ unsigned char dm[ed * ed];
+ unsigned char em[ed * ed];
+ unsigned char *lost[1];
+
+ for (i = 0; i < ed; i++)
+ memcpy(bm + (i * ed), ctx->enc_matrix + (in_idx[i] * ed), ed);
+
+ gf_invert_matrix(bm, dm, ed);
+
+ if (idx < ed)
+ memcpy(cm, dm + (idx * ed), ed);
+ else {
+ memcpy(em, ctx->enc_matrix + (idx * ed), ed);
+ _matmul(em, dm, cm, 1, ed, ed);
+ }
+
+ lost[0] = (unsigned char *)buf;
+ ec_init_tables(ed, 1, cm, ec_tbl);
+ ec_encode_data_sse(len, ed, 1, ec_tbl, input, lost);
+}
--
1.9.1
More information about the sheepdog
mailing list