局部变量的作用域

导航

<2010年3月>
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

统计

公告

我的邮件:

留言簿(7)

随笔分类

随笔档案

文章档案

我的链接

搜索

最新评论

阅读排行榜

评论排行榜

又长见识了

下面的代码居然能编译通过
void* mymemcpy( void* dest, const void* src, size_t count )
{
    
char* d = (char*)dest;
    
const char* s = (const char*)src;
    
int n = (count + 7/ 8// count > 0 assumed

    
switch( count & 7 )
    
{
    
case 0:  do {  *d++ = *s++;
    
case 7:        *d++ = *s++;
    
case 6:        *d++ = *s++;
    
case 5:        *d++ = *s++;
    
case 4:        *d++ = *s++;
    
case 3:        *d++ = *s++;
    
case 2:        *d++ = *s++;
    
case 1:        *d++ = *s++;
               }
 while (--> 0);
    }


    
return dest;
}
这种代码侧重于效率优化,但可读性实在不敢恭维。不过还是记录一下,以免以后再见到时不认识,被人笑话.

posted on 2005-08-24 15:34 局部变量 阅读(4163) 评论(17)  编辑 收藏

评论

# re: 又长见识了 2005-08-24 17:12 周星星

很老了,即使不用MMX,还可以当成int来赋值,都能再次提高速度。

# re: 又长见识了 2005-08-24 21:32 清风雨

但是,虽然。

个人还是觉得该鄙视的是这么写的人,不管他有什么理由。

# re: 又长见识了 2005-08-24 22:25 周星星

小声地对清风雨说:
你不需要的东西,比如运行效率,对其人而言未必就一定没用。
年初的时候Intel更改了向量计算和超线程,使得相关代码的复杂度平均提高了5到20倍,而效率最多才提升了5%,但人家依然弹冠相庆,客户也叫好。如果你在场,一定又被你鄙视了。
当然,我也不写这样的代码,其一因为我的工作要求没这么高,其二因为我的水平也不足以写出这样优秀的代码。但我不敢鄙视写类似的人,因为他们是软件工程里的研究者,而我们只是软件工程里的工人,所谓工人,要有工头管着,要有各种制度限制着,要有团队意思,要写大家都能看懂的代码,要使用统一的命名规范,要做一颗螺丝钉,要成为可以被互相替代的标准件,工人嘛,要的是其劳力,而不是其创造力。因为我只是一个卑微的工人,所以我不敢鄙视研究者。
如果按照市面上流传的所谓“规范的”编码标准,俺估计所有的C/C++标准函数库,标准模板库都会别人鄙视过够。其实还是Bjarne Stroustrup说得好:要想成为被大家所复用的功能,她就必须足够有效率。(原话我记不清楚了,应该来自于《The C++ Programming language》),我解释一下:1。你不能保证所有人都不关心运行效率;2。有了效率你可以用它来换取“简单”等性质,反之则不行。

# re: 又长见识了 2005-08-25 06:57 freedk

**解释一下这段代码,谢谢~~~~~~

# to freedk //re: 又长见识了 2005-08-25 07:52 一笑

count是n除以8的余数。所以除了要copy N轮(每轮8位),还要copy剩余的余数次。

在switch中,count决定要copy几位(次)。用count & 7能得出要copy的次数(7的二进制就是0111),之后就跳转到对应case标号。由于case中没有break所以会自动falldown,所以如果count为7就一直down到底执行7次,如果count为3就一直down到底执行3次。

while (--n > 0); 就不说了,是copy N轮。

这段代码妙就妙在能把诸多语法灵活的结合在一起,爽阿~~



# to freedk: 2005-08-25 08:51 周星星

小声地对清风雨说(续集): 
昨晚走的匆忙,所以就落下最后一段:我个人觉得你错在用对待工人的标准去对待研究员了,其实只有普通工人才需要写不一定好但大家都能理解的代码,因为与普通工人合作的也是普通工人,要考虑这个群体的理解力;其次作为工人,他好要保证老板能够轻易地炒他的鱿鱼且公司还不会因此受到损失,所以他要宁可牺牲代码的优秀也不能牺牲代码的易读性,确保替换他位置的人能够轻易接手。
但这些普通工人需要具备的规范标准对非普通工人而言并没有有益作用,所以也不具有约束力。

# re: 又长见识了 2005-08-25 09:36 flyljp

void* mymemcpy( void* dest, const void* src, size_t count )
{
    char* d = (char*)dest;
    const char* s = (const char*)src;
  //  int n = (count + 7) / 8; // count > 0 assumed
    int n = count >> 3;
    switch( count & 7 )
    {
              do {  *d++ = *s++;
    case 7:        *d++ = *s++;
    case 6:        *d++ = *s++;
    case 5:        *d++ = *s++;
    case 4:        *d++ = *s++;
    case 3:        *d++ = *s++;
    case 2:        *d++ = *s++;
    case 1:        *d++ = *s++;
    case 0          } //while (--n > 0);
                 while (n-- > 0)
    }

    return dest;
}

# re: 又长见识了 2005-08-25 09:37 boli


确实无聊~ :P
要写好这种高效率的代码,是不是要试N多种写法,然后要汇编代码?看那种实现的效率高?? 是从汇编代码中能看出效率吗?

# re: 又长见识了 2005-08-25 10:27 huangrg

在这当今这种硬件水平,效率不须要从细节处考虑(像上面的代码效率考虑有点过了,我看不懂上面的代码); 但整个系统在概要设计的还是要考虑效率的,比如缓冲处理、内在缓冲与分页等。

# re: 又长见识了 2005-08-25 18:37 my12doom

请问这个奇异的做法与标准库的汇编memcpy哪个更快?

# 这是VC的内部memcpy原代码。 2005-08-26 08:58 SevenCat

似乎没有vc自带的内部函数的memcpy快呀。

# re: 又长见识了 2005-08-26 08:59 SevenCat

我还有MMX的代码段,应该比这个都快。

# to my12doom: 2005-08-26 09:29 周星星

“请问这个奇异的做法与标准库的汇编memcpy哪个更快?”
---
1。标准库的实现并不是标准化的,因此虽然同样都是标准库,但实现方法可能不同,效率当然也有差别。为了追求最大的速度,memcpy基本上都是由汇编写成,由汇编编写的好处是可以最大程度的控制细节,防止编译器编译质量的影响。当然标准库的这种做法竟然受到boli和huangrg的批评也是始料不及的^_^
2。“这个奇异的做法”--- 假如你认为这段代码奇异的话,那么标准的memcpy做法那就更令你“奇异”了,因为mymemcpy中所有的受“清风雨”“鄙视”的,令“boli”觉得“无聊”的,还有“huangrg”所不愿意从“细节处考虑”“效率”的做法,在VC标准memcpy中都用到了,不仅仅如此,还有我一开始就提到的“当成int来赋值,都能再次提高速度。”的做法,都在VC标准memcpy中都用到了。
3。“哪个更快?”--- 毫无疑问,当然是现在的(主意这个修饰词)标准库中的memcpy更快,因为memcpy比mymemcpy更令boli和huangrg看不起嘛,用到的技巧更多。

[注]:mymemcpy中的方法也曾经是标准memcpy的实现方法之一,但现在的memcpy实现比她更复杂了,将来的memcpy也许更复杂。而这种“复杂化”的根源来自于硬件结构的复杂化,mymemcpy就是利用了现在CPU多流水线并发执行的能力。

# re: 周星星 2005-08-26 09:47 pAnic

多核CPU上似乎应该写一个多CPU版本的memcpy:P
另:
传统汇编下,因为存在
[ Base Address + Index * Scale + Displacement ]
这种寻址方式,memcpy的效率其实是非常好的。
使用了MMX之后,虽然理论效率有所提升,但是提升的幅度并不理想。而为了这点并不理想的效率提升,要付出浮点寄存器占用和多emms指令的代价,这有点得不偿失。

# re: 又长见识了 2005-08-26 10:43 局部变量

看大家讨论的这么热闹,我作为主人也发表一下个人看法:

我觉得这种代码应该用汇编去实现,高级语言应侧重可读性,对效率的要求相对较低(当然,如果有人能写出可读性、效率具佳的代码,他就是大师了)。而以效率为重点的代码应该用低级语言去实现,这也是从一方面提醒阅读代码的人“这段代码侧重效率,可读性不佳,要仔细阅读”。

这段代码是很多年前写出来的,它所面对的硬件体系结构与现在有很大不同,所以效率可能也没有现在的方法高。

我把它写在这原因有两点,一是提醒自己这种写法是符合c/c++语法规则的(以前从未见过,第一眼看到时以为不能编译),二是让自己记住对代码还有这样一种可选的优化手段。

# re: 又长见识了 2005-08-26 11:09 SevenCat

vc里面有个汇编版的memcpy,

# re: 又长见识了 2006-10-11 10:43 海阔天空

我也觉得这种代码有点不伦不类。如果站在追求效率的角度,不如直接使用汇编语言;如果站在可读性的角度,不如写点“正常”的代码。而且,就算是使用汇编语言,可读性也未必就比这段代码差。
以上所说并不反对周星星的言论:)

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]