| jianwu's profile乱舞的弦~~~张牙舞爪的warningPhotosBlogLists | Help |
|
15 June 程序员创业失败主要原因阿。。。从某条开始基本上全中。警醒下。
1)没有明确的生活目标。没有奋斗的中心目标或明确的努力主向,就没有成功的希望。
2)没有非同寻常的雄心抱负。 如果对凡事漠不关心,不想在人生中求发展,不愿付出代价,那么这样的人也将成功无望。 3)缺乏自律。 纪律来自自我控制,这意味着人必须控制所有的消极思想,只能先控制自己,才能控制环境。自制是人类面对的最艰巨任务,如果无法战胜自我,就会被自我征服。 4)拖拉。 这是失败最普遍的原因之一,拖拉“老人”存在于每个人心中的阴暗角落,正是因为一直都在等待“适当时机”,才开始做那些值得做的事情,其实时机永远不会“适当”。 5)缺乏毅力。 不管做什么,大部份人开始时都满怀信心,但却不能善始善终。大部份人一遇到失败就容易放弃。毅力是不可取代的。把毅力当座右铭奉行到底的人,发现失败会自行退下,失败是无法对抗毅力的。 6)消极的个性。 因为消极的个性,而将别人拒于千里之外者,不会有成功的希望。成功来自力量的运用,而力量又来自与他人的合作,消极的个性无法促成合作。 7)无法克制“不劳而获”的欲望。这种机体本能使很多人走向失败。 8)缺乏果断的决策力。 成功的人士会果断决策,然后如果有必要,再慢慢改进。失败者往往花很长时间才能作出决策,但很快就需要修改,而且要频繁修改。犹豫和拖拉是一对双包胎,只要找到其中一个就一定能找到另一个,所以必须趁它们没有将你完全束缚在失败的车轮上,果断地把它们消灭。 9)过度谨慎。 不主动抓住机会的人往往只能捡别人挑剩的机会,过度谨慎和不够谨慎都不可取,人生本来就充满偶然成分。 10)迷信与偏见。 迷信是恐惧的一种形式,也是无知的表现,成功人士心胸宽广,无所畏惧。 11)目标不专。“万事通,万事松”,要全心全意专注于一个主要目标。 12)缺乏热情。 没有热情,一个人就没有说服力,而且热情有一种感染力,一个人如果拥有热情,并能适当控制热情,往往会受到人们的欢迎。 13)偏执。心胸狭窄很难取得任何进步,偏执说明一个人不积极获取知识。 14)蓄意不忠。 诚实是一种不可替代的品质,受无法控制的环境所迫,一个人可能一时不忠诚,也不会带来永久的破坏。但是,如果一个人蓄意不忠,则无药可救。他的得行为迟早会被发现,他负出的代价可能是失去信誉,甚至失去自由。 15)自私和虚荣。这些品质问题好比亮起红灯,让人不敢靠近,是妨碍成功的致命因素。 16)猜测而不思考。 多数人往往漫不经心或者过于懒惰,不愿费心获取用于准确思考的事实。他们喜欢根据猜测或仓促得出的“结论”了事。观念改变人生!选择决定未来!行动决定成败! 来吧,老规矩,加上一张无关图片结束文章。前天北京vs天津的一场比赛,球迷打出的横幅:
[没插件,饮恨吧mina]
躲进小楼成一统之技术贴---release要比debug快么
读熊力先生的windows用户态程序高效排错的时候遇到这样一个问题:
------------------------------------------------------------------------------------------------------------ 分别在debug/release模式下运行下面的代码比较效率,会发现debug比release更快。你能找到原因吗?
------------------------------------------------------------------------------------------------------------ 拿vc6调了一下果然如此,根据cpu性能的不同相同的代码debug和release的性能差距竟然有3到4倍之多。决定把此问题搞清楚。
先拿出代码来吧: ----------------------------------------release部分代码----------------------------------------------------- 00401044 8B FB mov edi,ebx 00401046 83 C9 FF or ecx,0FFh ;循环次数 00401049 33 C0 xor eax,eax ;搜索内容 0040104B F2 AE repne scas byte ptr [edi] ;一直重复搜索到EDI字符串末尾的0 0040104D F7 D1 not ecx ;得到搜索次数,也就是字符串的完整长度 0040104F 2B F9 sub edi,ecx ;EDI后退到源字串头 00401051 8B C1 mov eax,ecx 00401053 8B F7 mov esi,edi ;ESI指向源字串地址 00401055 8B FD mov edi,ebp ;EBP指向目的字串地址(之前malloc结果) 00401057 C1 E9 02 shr ecx,2 ;双字mov 次数为长度除以2 0040105A F3 A5 rep movs dword ptr [edi],dword ptr [esi] ;内存拷贝 0040105C 8B C8 mov ecx,eax 0040105E 83 E1 03 and ecx,3 00401061 4A dec edx 00401062 F3 A4 rep movs byte ptr [edi],byte ptr [esi] ;完成剩余内容的拷贝 00401064 75 DE jne main+44h (00401044) ----------------------------------------------------------------------------------------------
debug版本调用的从strcat.asm就能够直接看到了,但是注释中实现的strcpy太过简单,不能显示汇编代码的全貌阿,以下是代码: ----------------------------------------------------------------------------------------------- mov edi,[esp+8] ; edi points to dest string -----------------------------------------------------------------------------------------------
1.最直接(或许也是最正确的)反应,编译器做多余的事情了,就检查debug和release模式下编译参数的区别。最终目标集中在了 /O2和/Ot上,使用/O2效率低,使用/Ot效率高。查阅资料之后发现 /O2 是 /Ot的超集,在我单独添加/O2的优化选项时,效率仍然是比较高的,开始怀疑资料的准确性。此路暂时不通放弃。
2。接下来就开始怀疑release版本内存对齐造成效率低下,检查后win32平台malloc()内存地址必然对齐。pass 副产品对齐版的malloc/free函数如下: /* align_size需要为2的倍数*/ void *aligned_malloc(size_t size, size_t align_size) {
char *ptr,*ptr2,*aligned_ptr; int align_mask = align_size - 1;
ptr=(char *)malloc(size + align_size + sizeof(int)); if(ptr==NULL) return(NULL);
ptr2 = ptr + sizeof(int); aligned_ptr = ptr2 + (align_size - ((size_t)ptr2 & align_mask));
ptr2 = aligned_ptr - sizeof(int); *((int *)ptr2)=(int)(aligned_ptr - ptr);
return(aligned_ptr); }
void aligned_free(void *ptr) {
int *ptr2=(int *)ptr - 1; ptr -= *ptr2; free(ptr); } 3。怀疑编译器release版本经常进行的内联优化上。检查代码以及常识告诉我这样的优化只能让release版本效率更高而已。
4.开始修改代码,使用动态从msvcrt中load strcpy,使用strncpy,自己实现注释版的strcpy 并强制inline,最终的结果都是相同,开始不得不关注进strcpy代码里了,debug版本的strcpy在效率上一定比release的效率高(一直不愿相信这个问题)。我们就只能再回过头来看上面的代码了。Release版本的代码算是比较常规的拷贝操作了,遍历获取字串长度,然后一个DWORD一个DWORD拷贝(很显然比单字节拷贝效率高),最后如果还有内容的话,就按照byte拷贝。下面是debug的, a) 首先检查是否内存对齐,未能对齐的话先诸字节拷贝直至对齐。对win32平台我们直接pass因为内存分配好就是对齐的。 b) 进入main_loop_entrance就比较神奇了,看下面这段神奇的代码,判断字符串是否到了结尾的,如果对一个DWORD拆分成4个byte分别判断,那4bytes一起拷贝节省下拉性能立刻浪费掉了,ms采取了一个非常聪明的办法
----------------------------------------------------------------------------------------------------------------- mov eax,dword ptr [ecx] ; read 4 bytes
简单的解释一下前三个字节我们可以这样判断,如果某字符减去0x1还要向前字节借位的话,那么该字符必然是’\0’,这样的话前一字节的最后一个bit必然会被借位。如此以是否向前一字节借位这一标准来判断该字节是否为’\0’.这样的方法适用于前三个字节,但是第四个字节怎么办?ms使用的方法是这样的以第四个字节的最高bit来判断,如果该字节为0,则在进行减法操作的时候,字节的最高位由于借位产生了1(不是纯0就不会借位到这个倒霉的最高bit身上),以此标准来判断该字节是否为0。 效率的节约也就在于此,dword进行拷贝以及直接对dword进行判断以查找字符串末尾,这是debug版的strcpy超越release版的地方。计算机的世界,算法为王。
不知道诸位有注意到的这个地方没,如果这个倒霉的bit是1其它bit为0呢?他也可能会误把这种情况的跟’\0’混淆的,因为代码无法判断这个1使本来就有的还是被借位出现的(本质就是0xor!0 = 1 1 xor!1 = 1两种情况无法判断),在进行进一步确认的时候就出了问题,不得已重新循环反而就损失了效率。当然这是一种极端的情况。可以填充数据为80xxxxxx来验证一下我们的怀疑。
针对这种方法如果我们想有所改进,单独的DWORD看来是希望不大了。可以结合cf寄存器来做下一步的工作。留一个note吧,以后思考。 整理下最近搞的wow外挂,release些经验来吧。。。。
|
|
|