快乐虾
http://blog.csdn.net/lights_joy/
本文适用于
ADSP-BF561
Visual DSP++ 5.0 (update 7)
x264-snapshot-20091118-2245
欢迎转载,但请保留作者信息
在第一个循环中,要计算像素点之差,它将需要16次读操作,虽然借助并行执行可以有效降低cycle数,但我们希望其效率能再高一点。
当传入的两个地址均以4对齐时,我们可以借助于561的byteunpack和byteop16m这两条指令,以整数方式读取数据,这样只需要4次的读操作,试试用汇编改写此函数(只考虑地址为4对齐的情况):
.section program
.global _x264_pixel_satd_8x4_s;
_x264_pixel_satd_8x4_s:
link 0x0;
[--sp] = (r7:3, p5:4);
// M2和M3保存行增量
// P5指向tmp数组
// I2和I3指向对齐的数据
// 程序开始,取参数
R6 = 4;
R1 = R1 - R6;
M2 = R1;
R7 = [FP + 0x14];
R7 = R7 - R6;
M3 = R7;
I2 = R0;
I3 = R2;
I0 = 0;
I1 = 0;
P5.H = HI(tmp);
P5.L = LO(tmp);
// 第一次循环
R2 = [I2++];
P4 = 4;
LSETUP(loop1_begin, loop1_end) LC0 = P4;
loop1_begin:
(R5, R4) = BYTEUNPACK R3:2 || R2 = [I2++M2] || NOP;
(R7, R6) = BYTEUNPACK R3:2 || R0 = [I3++] || NOP;
R7 = R7 << 8;
R6 = R6 << 8;
R3 = R5 + R7; // r5 = 7,3,6,2
R2 = R4 + R6; // r4 = 5,1,4,0
// 取P1
(R7, R6) = BYTEUNPACK R1:0 || R0 = [I3++M3] || NOP;
(R5, R4) = BYTEUNPACK R1:0;
R5 = R5 << 8;
R4 = R4 << 8;
R0 = R4 + R6; // r0 = 5,1,4,0
R1 = R5 + R7; // r1 = 7,3,6,2
// 计算, r4 => a0, r5 => a1, r6 => a2, r7 => a3
(R5, R4) = BYTEOP16M (R3:2, R1:0);
R0 = R1;
R2 = R3;
(R7, R6) = BYTEOP16M (R3:2, R1:0);
// HADAMA运算
R0 = R4 + R5, R1 = R4 - R5;
R2 = R6 + R7, R3 = R6 - R7;
R4 = R0 + R2, R5 = R0 - R2;
R6 = R1 + R3, R7 = R1 - R3 || [P5++] = R4 || NOP;
[P5++] = R6;
[P5++] = R5;
loop1_end: MNOP || [P5++] = R7 || R2 = [I2++];
// 第二个循环开始
P5.H = HI(tmp);
P5.L = LO(tmp);
I0 = P5;
R3 = [P5+0x30];
R2 = [P5+0x20];
R1 = [P5+0x10];
// 第一次循环
R6 = R2 + R3, R7 = R2 - R3 || R0 = [P5++] || NOP;
R4 = R0 + R1, R5 = R0 - R1;
R4 = R4 + R6, R6 = R4 - R6;
R5 = R5 + R7, R7 = R5 - R7;
R0 = 0;
R4 = ABS R4 (V) || [I0] = R0 || NOP;
R5 = ABS R5 (V) || R3 = [P5+0x30] || NOP;
R6 = ABS R6 (V) || R2 = [P5+0x20] || NOP;
R7 = ABS R7 (V) || R1 = [P5+0x10] || NOP;
R7 = R7 + R6;
R7 = R7 + R5;
R7 = R7 + R4, R6 = R7 - R4 || R5 = [I0] || NOP;
R5 = R5 + R7, R6 = R5 - R7 || R0 = [P5++] || NOP;
// 第二次循环
P4 = 3;
LSETUP(loop2_begin, loop2_end) LC0 = P4;
loop2_begin:
R6 = R2 + R3, R7 = R2 - R3 || [I0] = R5 || NOP;
R4 = R0 + R1, R5 = R0 - R1;
R4 = R4 + R6, R6 = R4 - R6;
R5 = R5 + R7, R7 = R5 - R7;
R4 = ABS R4 (V) || R3 = [P5+0x30] || NOP;
R5 = ABS R5 (V) || R2 = [P5+0x20] || NOP;
R6 = ABS R6 (V) || R1 = [P5+0x10] || NOP;
R7 = ABS R7 (V);
R7 = R7 + R6;
R7 = R7 + R5;
R7 = R7 + R4, R6 = R7 - R4 || R5 = [I0] || NOP;
loop2_end: R5 = R5 + R7, R6 = R5 - R7 || R0 = [P5++] || NOP;
// 计算平均值
A0 = R5;
r4=a1.l+a1.h, r0=a0.l+a0.h;
r0 >>= 1;
// 退出
(r7:3, p5:4) = [sp++];
unlink;
rts;
_x264_pixel_satd_8x4_s.end:
.section data1
.byte4 tmp[16] = 0;
这一段代码比c生成的代码效率略高一点,c版本的代码需要245个cycle,而这个版本则只需要210个cycle,当然这是以损失通用性为代价的。本来561也提供了对不对齐数据的处理,但是此时将需要6次读操作和其它的一些辅助判断,效率反而不如直接取数进行计算。
最终我们先判断地址是否以4对齐,如果是则运行汇编代码,否则仍运行原来的代码,运行结果:
encoded 301 frames, 2.60 fps, 1136.47 kb/s
总共使用了67659M cycle,效率提高了2%。
近日,我家6岁的小姑娘参加了第六届POP全国少儿英语风采大赛,拉票进行中(2011-6-15前)。
请帮忙点击新东方网站的链接:
http://popdasai.xdf.cn/toupiao.php?do=space&uid=4237
投她一票,谢谢!
在ADSP-BF561上使用x264(7):x264_pixel_satd_8x4(2009-12-2)
在ADSP-BF561上使用x264(6):get_ref(2009-11-25)
在ADSP-BF561上使用x264(5):Writeback vs writethrough(2009-11-24)
在ADSP-BF561上使用x264(4):确认热点(2009-11-24)
在ADSP-BF561上使用x264(4):打开cache(2009-11-24)
在ADSP-BF561上使用x264(3):正确性验证(2009-11-24)
ADSP-BF561软件优化(2):移植x264(2009-11-19)
ADSP-BF561软件优化(1):开篇(2009-11-18)