行优先和列优先

计算新向量的各个分量时,分别要乘以矩阵中的不连续元素,这样无法充分利用硬件的向量乘法指令。

于是有了 column_major 排列的矩阵

计算新向量的各个分量时,分别乘以矩阵中的连续元素,这样可以充分利用硬件的向量乘法指令,提高效率。

#define C8NUM 8
#define  C4NUM 4
#define UP_ROUND(x, y) (((x) + (y) - (1)) / (y) * (y))

void RowMajor2Col8Major(const float *src_ptr, float *dst_ptr, int row, int col) {
    int row8 = row / C8NUM * C8NUM; // 1
    int col_skip = col / C4NUM * C4NUM; // 12
    int skip_size = C4NUM; // 4
    const float *src_r = src_ptr;
    float *dst_r = dst_ptr;

    int ri = 0;
    for (; ri < row8; ri += C8NUM) {
        int ci = 0;
        for (; ci < col_skip; ci += skip_size) {
            const float *src_c = src_r + ci;
            float *dst_c = dst_r + ci * C8NUM;
            for (int tr = 0; tr < 8; tr++) {
                for (int tc = 0; tc < 4; tc++) {
                    dst_c[tc * 8 + tr] = src_c[tr * col + tc];
                }
            }
        }
        for (; ci < col; ci++) {
            const float *src_c = src_r + ci;
            float *dst_c = dst_r + ci * C8NUM;
            for (int i = 0; i < C8NUM; i++) {
                dst_c[i] = src_c[i * col];
            }
        }
        src_r += C8NUM * col;
        dst_r += C8NUM * col;
    }
    for (; ri < row; ri++, src_r += col, dst_r++) {
        for (int i = 0; i < col; i++) {
            dst_r[i * C8NUM] = src_r[i];
        }
    }

    for (; ri < UP_ROUND(row, C8NUM); ri++, dst_r++) {
        for (int i = 0; i < col; i++) {
            dst_r[i * C8NUM] = 0;
        }
    }
}

int main() {
    std::cout << "Hello, World!" << std::endl;
//    假设矩阵为10(行) * 14(列)
    float *src = (float *) malloc(140 * sizeof(float ));
    for (int i = 0; i< 140; i++) {
        src[i] = i;
    }
    // 转换成列优先。
    // (10 + 8 -1 / 8) *8 =16
    // 改成 colour8magor, 列转行,
    float *dst = (float *) malloc(16 * 14 * sizeof(float ));
    for (int i = 0; i < 16 * 14 ; i++) {
        dst[i] = 1;
        printf("%d, %.1f   ", i, dst[i]);
    }
    RowMajor2Col8Major(src, dst, 10, 14);
    for (int i = 0; i < 16 * 14 ; i++) {
        if (i % 8 ==0) {
            printf("\n");
        }
        printf("i:%d, %.1f   ", i, dst[i]);
    }
    return 0;
}

 转化成列有限,8列。则计算时。如果之前的数据行转成列之后,超过8列,则在另起行。从如下打印中可以看到。

i:0, 0.0   i:1, 14.0   i:2, 28.0   i:3, 42.0   i:4, 56.0   i:5, 70.0   i:6, 84.0   i:7, 98.0
i:8, 1.0   i:9, 15.0   i:10, 29.0   i:11, 43.0   i:12, 57.0   i:13, 71.0   i:14, 85.0   i:15, 99.0
i:16, 2.0   i:17, 16.0   i:18, 30.0   i:19, 44.0   i:20, 58.0   i:21, 72.0   i:22, 86.0   i:23, 100.0
i:24, 3.0   i:25, 17.0   i:26, 31.0   i:27, 45.0   i:28, 59.0   i:29, 73.0   i:30, 87.0   i:31, 101.0
i:32, 4.0   i:33, 18.0   i:34, 32.0   i:35, 46.0   i:36, 60.0   i:37, 74.0   i:38, 88.0   i:39, 102.0
i:40, 5.0   i:41, 19.0   i:42, 33.0   i:43, 47.0   i:44, 61.0   i:45, 75.0   i:46, 89.0   i:47, 103.0
i:48, 6.0   i:49, 20.0   i:50, 34.0   i:51, 48.0   i:52, 62.0   i:53, 76.0   i:54, 90.0   i:55, 104.0
i:56, 7.0   i:57, 21.0   i:58, 35.0   i:59, 49.0   i:60, 63.0   i:61, 77.0   i:62, 91.0   i:63, 105.0
i:64, 8.0   i:65, 22.0   i:66, 36.0   i:67, 50.0   i:68, 64.0   i:69, 78.0   i:70, 92.0   i:71, 106.0
i:72, 9.0   i:73, 23.0   i:74, 37.0   i:75, 51.0   i:76, 65.0   i:77, 79.0   i:78, 93.0   i:79, 107.0
i:80, 10.0   i:81, 24.0   i:82, 38.0   i:83, 52.0   i:84, 66.0   i:85, 80.0   i:86, 94.0   i:87, 108.0
i:88, 11.0   i:89, 25.0   i:90, 39.0   i:91, 53.0   i:92, 67.0   i:93, 81.0   i:94, 95.0   i:95, 109.0
i:96, 12.0   i:97, 26.0   i:98, 40.0   i:99, 54.0   i:100, 68.0   i:101, 82.0   i:102, 96.0   i:103, 110.0
i:104, 13.0   i:105, 27.0   i:106, 41.0   i:107, 55.0   i:108, 69.0   i:109, 83.0   i:110, 97.0   i:111, 111.0
i:112, 112.0   i:113, 126.0   i:114, 0.0   i:115, 0.0   i:116, 0.0   i:117, 0.0   i:118, 0.0   i:119, 0.0
i:120, 113.0   i:121, 127.0   i:122, 0.0   i:123, 0.0   i:124, 0.0   i:125, 0.0   i:126, 0.0   i:127, 0.0
i:128, 114.0   i:129, 128.0   i:130, 0.0   i:131, 0.0   i:132, 0.0   i:133, 0.0   i:134, 0.0   i:135, 0.0
i:136, 115.0   i:137, 129.0   i:138, 0.0   i:139, 0.0   i:140, 0.0   i:141, 0.0   i:142, 0.0   i:143, 0.0
i:144, 116.0   i:145, 130.0   i:146, 0.0   i:147, 0.0   i:148, 0.0   i:149, 0.0   i:150, 0.0   i:151, 0.0
i:152, 117.0   i:153, 131.0   i:154, 0.0   i:155, 0.0   i:156, 0.0   i:157, 0.0   i:158, 0.0   i:159, 0.0
i:160, 118.0   i:161, 132.0   i:162, 0.0   i:163, 0.0   i:164, 0.0   i:165, 0.0   i:166, 0.0   i:167, 0.0
i:168, 119.0   i:169, 133.0   i:170, 0.0   i:171, 0.0   i:172, 0.0   i:173, 0.0   i:174, 0.0   i:175, 0.0
i:176, 120.0   i:177, 134.0   i:178, 0.0   i:179, 0.0   i:180, 0.0   i:181, 0.0   i:182, 0.0   i:183, 0.0
i:184, 121.0   i:185, 135.0   i:186, 0.0   i:187, 0.0   i:188, 0.0   i:189, 0.0   i:190, 0.0   i:191, 0.0
i:192, 122.0   i:193, 136.0   i:194, 0.0   i:195, 0.0   i:196, 0.0   i:197, 0.0   i:198, 0.0   i:199, 0.0
i:200, 123.0   i:201, 137.0   i:202, 0.0   i:203, 0.0   i:204, 0.0   i:205, 0.0   i:206, 0.0   i:207, 0.0
i:208, 124.0   i:209, 138.0   i:210, 0.0   i:211, 0.0   i:212, 0.0   i:213, 0.0   i:214, 0.0   i:215, 0.0
i:216, 125.0   i:217, 139.0   i:218, 0.0   i:219, 0.0   i:220, 0.0   i:221, 0.0   i:222, 0.0   i:223, 0.0
Process finished with exit code 0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值