求教一个执行效率的问题

码侬 2011-04-30 02:26:12

code 1:
int R=(int)(pY[j] * 4194304 - pCb[j] * 10333   + pCr[j] * 5727677 - 731820157 + 2097152)>>22);
int G=(int)((pY[j] * 4194304 - pCb[j] * 1399048 - pCr[j] * 2935263 + 554791958 + 2097152)>>22);
int B=(int)((pY[j] * 4194304 + pCb[j] * 7263892 - pCr[j] * 25573 - 926504885 + 2097152)>>22);

code 2:
int R = (int)((pY[j] * 16384 - pCb[j] * 40    + pCr[j] * 22374 - 2850480) >> 14);
int G = (int)((pY[j] * 16384 - pCb[j] * 5465 - pCr[j] * 11466 + 2175348) >> 14);
int B = (int)((pY[j] * 16384 + pCb[j] * 28375 - pCr[j] * 100 - 3610968) >> 14);



都是Release版本,上面两段代码那个效率更高一些呢?

我认为两个应该一样才对,但是实际 code1 效率更高。
循环一张图像1000次,
code1 耗时 6s
code2 耗时 8s

注:
除了这三行代码不一样,其余全都一样,怎么解释呢?
...全文
182 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
comefromtust 2011-05-05
  • 打赏
  • 举报
回复
亦没有合适答案。
jameshooo 2011-05-02
  • 打赏
  • 举报
回复
如果流程控制不好,MMX不见得能提高效率,甚至可能降低性能,因为为了MMX而增加的流控指令造成的CPU浪费有可能超过MMX带来的CPU性能提升。当然这都是猜测。
码侬 2011-05-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 jameshooo 的回复:]
实在看不出区别,或许 imul 和 sar 指令的效率会有所不同。还有,乘以大整数有没有可能导致溢出?两种算法的结果完全相同吗?
[/Quote]

结果完全一样,只是一个精度更高一些。
不会溢出的,因为 Y,Cb,Cr的值是在 0~255.

循环1000次,实验的多次,结果都一样,应该不是随机问题,使用高精度定时器,已经到了6秒钟了。可以在自己的电脑上试一下,随机赋值,看看是不是如此。

汇编代码可能不准确,因为汇编是Debug版,试验的是Release版。

代码的产生是源于此:
code1,是两个DWORD相乘,不能使用MMX的点乘指令 -- pmaddwd
code2,是两个WORD相乘,可以使用点成指令。
因为一个pmaddwd指令可以代替六个指令(四个乘,两个加),本来要提高效率的,结果导致效率下降,经过反复核查,才发现的这个现象。

傻X 2011-05-02
  • 打赏
  • 举报
回复
太高深了,时间复杂度和空间复杂度
副组长 2011-05-02
  • 打赏
  • 举报
回复
一样的东西。

1000次,1高。10000次说不定就是2高呢,多试试吧,看来像随机的。
Eleven 2011-05-01
  • 打赏
  • 举报
回复
jameshooo 2011-05-01
  • 打赏
  • 举报
回复
实在看不出区别,或许 imul 和 sar 指令的效率会有所不同。还有,乘以大整数有没有可能导致溢出?两种算法的结果完全相同吗?
jameshooo 2011-05-01
  • 打赏
  • 举报
回复
我猜测你是想把YCbCr颜色转换成RGB颜色,本来是一种浮点型转换公式,为了提高运算效率,把公式变成整形转换公式,通过乘以大整数再用移位代表除法。对否?

效率谁高不知道,看看汇编代码再来判定吧。
MoXiaoRab 2011-05-01
  • 打赏
  • 举报
回复
压力好大
码侬 2011-05-01
  • 打赏
  • 举报
回复
两段汇编也没有很大区别:
code1:效率高
0040D446   mov         edx,dword ptr [ebp+8]
0040D449 add edx,dword ptr [ebp-4]
0040D44C xor eax,eax
0040D44E mov al,byte ptr [edx]
0040D450 shl eax,16h
0040D453 mov ecx,dword ptr [ebp+0Ch]
0040D456 add ecx,dword ptr [ebp-4]
0040D459 xor edx,edx
0040D45B mov dl,byte ptr [ecx]
0040D45D imul edx,edx,285Dh
0040D463 sub eax,edx
0040D465 mov ecx,dword ptr [ebp+10h]
0040D468 add ecx,dword ptr [ebp-4]
0040D46B xor edx,edx
0040D46D mov dl,byte ptr [ecx]
0040D46F imul edx,edx,5765BDh
0040D475 lea eax,[eax+edx-2B7EB07Dh]
0040D47C sar eax,16h
0040D47F mov dword ptr [R],eax


code2:效率低

0040D446 mov edx,dword ptr [ebp+8]
0040D449 add edx,dword ptr [ebp-4]
0040D44C xor eax,eax
0040D44E mov al,byte ptr [edx]
0040D450 shl eax,0Eh
0040D453 mov ecx,dword ptr [ebp+0Ch]
0040D456 add ecx,dword ptr [ebp-4]
0040D459 xor edx,edx
0040D45B mov dl,byte ptr [ecx]
0040D45D imul edx,edx,28h
0040D460 sub eax,edx
0040D462 mov ecx,dword ptr [ebp+10h]
0040D465 add ecx,dword ptr [ebp-4]
0040D468 xor edx,edx
0040D46A mov dl,byte ptr [ecx]
0040D46C imul edx,edx,5766h
0040D472 lea eax,[eax+edx-2B7EB0h]
0040D479 sar eax,0Eh
0040D47C mov dword ptr [R],eax
码侬 2011-05-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 jameshooo 的回复:]
我猜测你是想把YCbCr颜色转换成RGB颜色,本来是一种浮点型转换公式,为了提高运算效率,把公式变成整形转换公式,通过乘以大整数再用移位代表除法。对否?

效率谁高不知道,看看汇编代码再来判定吧。
[/Quote]

对的,本来是这样的:
//double dR = (pY[j] - 0.00246351 * pCb[j] + 1.36558478 * pCr[j] - 174.47952208);
//double dG = (pY[j] - 0.33355916 * pCb[j] - 0.69982140 * pCr[j] + 132.27271048);
//double dB = (pY[j] + 1.73184701 * pCb[j] - 0.00609719 * pCr[j] - 220.89597832);

除法不如乘法效率高,浮点不如整数效率高。
可以把浮点数运算转化为整数运算,提高效率。

但是两段代码怎么差那么多呢。
  • 打赏
  • 举报
回复
等待高人解答
jiangfaqun 2011-04-30
  • 打赏
  • 举报
回复
我就不明白你的那些常数是这吗得来的
_free 2011-04-30
  • 打赏
  • 举报
回复
哦,2的代码整齐,其他的不懂
jameshooo 2011-04-30
  • 打赏
  • 举报
回复
完全看不懂
hztj2005 2011-04-30
  • 打赏
  • 举报
回复
不可理解
海盗医生 2011-04-30
  • 打赏
  • 举报
回复
应该跟位运算符>>有关 一个是22 一个是14
quwei197874 2011-04-30
  • 打赏
  • 举报
回复
应该是1的效率高吧.
csx007700 2011-04-30
  • 打赏
  • 举报
回复
呃 编译出来看下汇编应该可以得到答案
码侬 2011-04-30
  • 打赏
  • 举报
回复
code 1:
int R = (int)((pY[j] * 4194304 - pCb[j] * 10333   + pCr[j] * 5727677 - 731820157 + 2097152) >> 22);
int G = (int)((pY[j] * 4194304 - pCb[j] * 1399048 - pCr[j] * 2935263 + 554791958 + 2097152) >> 22);
int B = (int)((pY[j] * 4194304 + pCb[j] * 7263892 - pCr[j] * 25573 - 926504885 + 2097152) >> 22);


code 2:
int R = (int)((pY[j] * 16384 - pCb[j] * 40    + pCr[j] * 22374 - 2850480) >> 14);
int G = (int)((pY[j] * 16384 - pCb[j] * 5465 - pCr[j] * 11466 + 2175348) >> 14);
int B = (int)((pY[j] * 16384 + pCb[j] * 28375 - pCr[j] * 100 - 3610968) >> 14);


15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧