计算新向量的各个分量时,分别要乘以矩阵中的不连续元素,这样无法充分利用硬件的向量乘法指令。
于是有了 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