[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