五千年(敝帚自珍)

主题:【原创】继续关于swap的讨论 -- 不锈钢破锣

共:💬22 🌺5
全看树展主题 · 分页首页 上页
/ 2
下页 末页
家园 对这个没什么研究。。。

不过,讲究速度的,一般都是下层的应用,CODE不大。。(虽然全系统全部CODE 可能很大)。。。如果用c++写的,SIZE恐怕不小,少几条指令也好不了多少。。。这个我是瞎猜的。。。如果你有例子反驳一下,最好。。。

家园 要看具体应用。

也许速度从两秒减少到一秒,不算什么。

但是我的有些应用问题要用几十个CPU

并行计算几个月才有结果。这样,两个月

和四个月的区别还是很大的,所以在速度上

需要很“抠门儿”。呵呵。

具体例子太繁琐了,如果有时间我简化一下

贴上来。还是蛮有意思的。

家园 【原创】补充一点

那为什么现在比较常用的方法还是使用临时变量呢?两个原因,一个是赋值运算比逻辑运算的速度更快;另一个是在编程方面,使用临时变量可读性更高。

更重要的原因,如果a,b是一个复杂的object,后两种做法很可能就不work,因为一般class的design,通常都会实现operator=(),而不一定会实现operator+, operator-,几乎很少会实现XOR operator。

因此第一种做法是上面唯一一个能handle generic case的,同时您也提到了,可读性好,效率也不差(实际上如果a,b是object,效率应该比后两种更好)。

严格说来,后两种做法(不使用临时变量),是违反软件工程的基本原则,因为会使code reusability大幅度降低,也不容易维护。

除了在interview中刻意为难一下Interviewee,实际编程工作中,一般不会用后两种做法。

家园 是这样的,首先寄存器的读取速度远远快于内存。

寄存器在CPU内部,这样就不需要完成内存送到reg和reg存回内存这个步骤了,运算速度提高的不是一点半点,特别是复杂的算术运算。直接内存读取当然可以,但是人家编译器多半不肯那,

其次,编译器在生成中间代码的时候,会采用线性优化的方法来分配寄存器,是否会多分配出一个Reg取决于最后优化的结果。所以对于使用临时变量的那段代码,这里的temp是占有一个内存空间还是寄存器很难说。

可能的一个结果就是给a或者b一个reg,其余在内存中完成操作。

---------------

LOAD a R0;

MOV b a;

MOV R0 b;

---------------

不使用temp的情况下,编译器多半就照着代码翻,加法和赋值的开销基本是一样的,所以代码可能不变。同样的,分配寄存器按照上面说的来进行。

家园 这该至少讲到cache里去吧

楼主的东东是在机器语言才可比较

机器语言里(说错了的只管扔鸡蛋上来,俺有篮子接)

temp=a;

a=b;

b=temp.

是这样做的

控制器控制寄存器a放a

控制器控制寄存器b放b

控制器控制寄存器a取a给寄存器c放a

控制器控制寄存器b取b给寄存器a放b

控制器控制寄存器c取a给寄存器b放a

a = a+b;

b = a-b;

a = a-b;

是这样走

控制器控制寄存器a放a

控制器控制寄存器b放b

控制器控制寄存器a取a 寄存器b取b 给计算器计算a+b

控制器控制 计算器把a+b=A送寄存器a放A

控制器控制 寄存器a取A 寄存器b取b 给计算器计算A-b a+b-b

控制器控制 计算器把A-b=a送寄存器b放a

控制器控制 寄存器a取A 寄存器b取a 给计算器计算A-a a+b-a

控制器控制 计算器把A-b=b送寄存器a放b

所以牺牲空间换时间,牺牲时间换空间

家园 呵呵,这个答案有问题

a和b可能是同一个地址的引用,例如在选择排序或是洗牌算法中调用swap(a[i], a[j])时可能i与j相等。

如果我没记错的话,TAOCP里的题目是有所不同的,所以我不是说K大的答案有问题。

如果是支持赋值表达式的语言,可以有如下的答案:

a = a + b - (b = a);

但这个方法和“经典答案”一样,如同楼下有人提到的,从编译器偷了临时变量。

这种题和IOCCC一样,作为趣味智力题就很好,但并不适合在实际中使用。

另外,我认为仅这个题目是上纲不到“计算机科学”的,对照自然科学的说法,说是属于“计算机工程”或“应用计算机学”比较合适。

家园 有意思的问题

应该在计算机结构(computer architecture)的范围内讨论比较有意义。否则编译软件的优化很可能把你的各种办法都优化成相同的代码了。

事实上如果我们假设a,b都是寄存器变量的话,不少处理器都可以直接提供交换指令。例如x86处理器的

"xchg ax,bx;"

就是交换两个16位寄存器的内容。

通常情况是,在使用临时变量作显式交换时,编译软件较容易判断出程序员的目的,从而直接使用交换指令。

全看树展主题 · 分页首页 上页
/ 2
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河