From 3e856ec04ebe3cf072939641ba6cd7871bfefc32 Mon Sep 17 00:00:00 2001
From: AlexeyAB <alexeyab84@gmail.com>
Date: Thu, 09 Aug 2018 22:27:20 +0000
Subject: [PATCH] Optimized: transpose

---
 src/convolutional_layer.c |   25 ------------
 src/gemm.c                |   61 ++++++++++++++++--------------
 2 files changed, 33 insertions(+), 53 deletions(-)

diff --git a/src/convolutional_layer.c b/src/convolutional_layer.c
index a820588..3c9efdd 100644
--- a/src/convolutional_layer.c
+++ b/src/convolutional_layer.c
@@ -637,32 +637,9 @@
     //printf("\n align_weights_size = %d, k = %d, m = %d, lda = %d \n", align_weights_size, k, m, k);
     //printf("\n align_bit_weights_size = %d, k = %d, m = %d, new_lda = %d \n", align_bit_weights_size, k, m, new_ldb);
 
-    // transpose and align B
-    int i, j;
-    //#pragma omp parallel for
-    /*
-    for (i = 0; i < n; ++i) {
-        for (j = 0; j < k; ++j) {
-            t_input[i*new_ldb + j] = b[j*n + i];
-        }
-    }*/
-    //transpose_block_SSE4x4(float *A, float *B, const int n, const int m, const int lda, const int ldb, const int block_size)
-
-    //transpose_block(b, t_input, k, n, n, new_ldb, 16);
-
-    int blocksize = 1;
-    int mod_k = 1, mod_n = 1;
-    for (i = 2; i < 256; i *= 2)
-        if (k % i == 0) mod_k = i;
-
-    for (i = 2; i < 256; i *= 2)
-        if (n % i == 0) mod_n = i;
-
-    blocksize = (mod_k < mod_n) ? mod_k : mod_n;
-
+    int blocksize = 64;
     transpose_block_SSE4x4(b, t_input, k, n, n, new_ldb, blocksize);
 
-    //transpose_block(b, t_input, k, n, n, new_ldb, blocksize);
     //printf("\n blocksize = %d \n", blocksize);
 
     float_to_bit(t_input, *t_bit_input, t_intput_size);
diff --git a/src/gemm.c b/src/gemm.c
index ff5edfa..4a7dad7 100644
--- a/src/gemm.c
+++ b/src/gemm.c
@@ -686,47 +686,50 @@
 
 static inline void transpose4x4_SSE(float *A, float *B, const int lda, const int ldb)
 {
-    __m128 row1 = _mm_load_ps(&A[0 * lda]);
-    __m128 row2 = _mm_load_ps(&A[1 * lda]);
-    __m128 row3 = _mm_load_ps(&A[2 * lda]);
-    __m128 row4 = _mm_load_ps(&A[3 * lda]);
+    __m128 row1 = _mm_loadu_ps(&A[0 * lda]);
+    __m128 row2 = _mm_loadu_ps(&A[1 * lda]);
+    __m128 row3 = _mm_loadu_ps(&A[2 * lda]);
+    __m128 row4 = _mm_loadu_ps(&A[3 * lda]);
     _MM_TRANSPOSE4_PS(row1, row2, row3, row4);
-    _mm_store_ps(&B[0 * ldb], row1);
-    _mm_store_ps(&B[1 * ldb], row2);
-    _mm_store_ps(&B[2 * ldb], row3);
-    _mm_store_ps(&B[3 * ldb], row4);
+    _mm_storeu_ps(&B[0 * ldb], row1);
+    _mm_storeu_ps(&B[1 * ldb], row2);
+    _mm_storeu_ps(&B[2 * ldb], row3);
+    _mm_storeu_ps(&B[3 * ldb], row4);
 }
 
 void transpose_block_SSE4x4(float *A, float *B, const int n, const int m,
     const int lda, const int ldb, const int block_size)
 {
     int i;
-    if (block_size % 4 == 0) {
-        #pragma omp parallel for
-        for (i = 0; i < n; i += block_size) {
-            int j, i2, j2;
+    #pragma omp parallel for
+    for (i = 0; i < n; i += block_size) {
+        int j, i2, j2;
+        //int max_i2 = (i + block_size < n) ? (i + block_size) : n;
+        if (i + block_size < n) {
+            int max_i2 = i + block_size;
             for (j = 0; j < m; j += block_size) {
-                int max_i2 = i + block_size < n ? i + block_size : n;
-                int max_j2 = j + block_size < m ? j + block_size : m;
-                for (i2 = i; i2 < max_i2; i2 += 4) {
-                    for (j2 = j; j2 < max_j2; j2 += 4) {
-                        transpose4x4_SSE(&A[i2*lda + j2], &B[j2*ldb + i2], lda, ldb);
+                //int max_j2 = (j + block_size < m) ? (j + block_size) : m;
+                if (j + block_size < m) {
+                    int max_j2 = j + block_size;
+                    for (i2 = i; i2 < max_i2; i2 += 4) {
+                        for (j2 = j; j2 < max_j2; j2 += 4) {
+                            transpose4x4_SSE(&A[i2*lda + j2], &B[j2*ldb + i2], lda, ldb);
+                        }
+                    }
+                }
+                else {
+                    for (i2 = i; i2 < max_i2; ++i2) {
+                        for (j2 = j; j2 < m; ++j2) {
+                            B[j2*ldb + i2] = A[i2*lda + j2];
+                        }
                     }
                 }
             }
         }
-    }
-    else {
-        #pragma omp parallel for
-        for (i = 0; i < n; i += block_size) {
-            int j, i2, j2;
-            for (j = 0; j < m; j += block_size) {
-                int max_i2 = i + block_size < n ? i + block_size : n;
-                int max_j2 = j + block_size < m ? j + block_size : m;
-                for (i2 = i; i2 < max_i2; ++i2) {
-                    for (j2 = j; j2 < max_j2; ++j2) {
-                        B[j2*ldb + i2] = A[i2*lda + j2];
-                    }
+        else {
+            for (i2 = i; i2 < n; ++i2) {
+                for (j2 = 0; j2 < m; ++j2) {
+                    B[j2*ldb + i2] = A[i2*lda + j2];
                 }
             }
         }

--
Gitblit v1.10.0