2008年10月23日星期四

刚才有客户投诉微软XP黑屏

用户:你好,请问这里是微软吗?
微软:是的,请问您有什么事吗?
用户:前几天看到你们发布公告,不是说好了要黑屏的吗?我都等一天了,怎么还不黑啊。。。。
微软:#%$^&@
用户:你们到底黑不黑了?
微软:…….
用户:说啊,你们黑不黑?
微软:黑… 盗版的才黑,你是盗版吗?
用户:是啊,100%盗版,绝对盗版.
微软:那不应该啊,对了,你打开自动更新了吗?
用户:打开了啊,早早的就打开了,就等着看黑屏呢!
微软;##$%^&%$#@$%…
用户:怎么了?不需要打开啊?
微软:需要,需要!
用户:那咋还不黑呢?
微软:你的自动更新有提示你下载补丁吗?
用户:这倒没有,我等老半天了,最后等不了了,自己去你们网站上下了一个,结果还是不黑,你说这玩意整的!
微软:….
微软:对不起,先生,我们暂时无法解决你的问题,呆会找技术人员跟你联系,谢谢!

挂机…………

刚才我电脑黑屏了

今天我的黑屏了
仔细一查,是显示器线松了
后来我还发现了,别人的盗版的都一小时黑一次屏,然后大家就能休息一下眼睛,活动活动身体,我感觉微软的设计真的非常人性化,所以我就把自己用的正版卸载了,换盗版的了
太人性化了
嘿 您还真别说 自从用上盗版之后 腰也不酸了 腿也不疼了 走路也有劲了 身体倍棒 吃嘛嘛香 微软 精心呵护您的身体

电脑用户保持眼睛湿润

转贴自http://www.uho.com.tw/hotnews.asp?aid=4377

信息科技时代来临,计算机使用的普及,不少长期在计算机前工作的朋友常常会觉得眼睛干涩、视力模糊,这其实很可能就是干眼症的早期表现。提醒各位,对这种状况不可掉以轻心。

根据美国全国职业保健与安全研究所的调查显示,每天在计算机前工作3小时以上的人之中,有90%的人眼睛有问题,表现症状是:眼睛干涩、头痛、烦躁、疲劳、注意力难以集中等,这种计算机视力综合症就是典型的干眼症。日本眼科医学会的调查结果也显示,每3名长期面对计算机屏幕的工作人员中,就有1名患有干眼症。因此,在计算机前工作的人需要特别注意保护眼睛。

诺贝尔眼科医师 张朝凯表示泪液主要有三大功能:一是湿润眼球;二是保持眼球的洁净;三是与眼屈光有关。如果泪液分泌太少或者蒸发过多,角膜表面和结膜表面得不到足够的滋润,看东西时,就会出现视物不清、眼睛酸涩等状况。而眨眼是一种保护性的神经反射作用,使泪水均匀地涂在角膜和结膜表面,以保持其润湿。正常人每分钟眨眼约为1020次,倘若长时间凝视计算机屏幕,眨眼次数常减少至每分钟45次,眼睛便会感到干涩。

防治干眼症,最重要还是让眼睛充分获得休息。若是无法避免与计算机为伍,我建议计算机屏幕上显示的亮度应为周围光线的3倍左右,屏幕的上端稍微低于视线10~15度,眼睛与计算机屏幕距离要保持在30cm以上;在计算机前每工作1个小时,就应该闭目休息10分钟,并用手按摩放松眼部周围的肌肉,或者眺望远处的景物等;此外,也可使用一些人工泪液来滋润眼睛,或刻意增加眨眼的次数,在饮食方面,可多吃富含维生素A的食物,例如胡萝卜和动物肝脏等。

别漠视干眼症,往往一开始只是感到眼睛干燥和酸涩,眼睛尚处于功能性损伤的阶段,但是如果这时还不注意保护眼睛,持续让你的眼睛长期处于干燥的状态,则可能引起角膜上皮细胞的脱落,造成器质性的损伤,当症状进一步恶化,则可能严重影响视力。最后还是要再次叮咛你,注意生活饮食规律正常,避免熬夜,才是眼睛保健根本之道。

(转)如何加速for loop? (C/C++)

Introduction
原题如下
有一个for循环,从0加到100,可是我觉得它不够快,要怎样才能让她更快呢?(不可以用数学公式)

for(i = 0; i <= 100; i++)
s = s + i;


我能想到的解法
1.调compiler参数,vc++和gcc都有-o可以调,可以optimize for speed,是最懒的方式。

2.善用多核心:

/*
(C) OOMusou 2008 http://oomusou.cnblogs.com

Filename : parallel_for_100.c
Compiler : Visual C++ 8.0
Description : Demo how to parallel sum 0 to 100
Release : 03/14/2008 1.0
*/
#include <stdio.h>
#include "omp.h"

int main() {
int i;
int s = 0;

printf("Number of core : %d\n", omp_get_num_procs());
printf("Number of threads : %d\n", omp_get_num_threads());

#pragma omp parallel for
for(i = 0; i <= 100; ++i) {
printf("thread %d : %d\n", omp_get_thread_num(), s = s + i);
}
printf("%d\n", s);
}

行结果

mber of core : 2
mber of threads : 1
read 0 : 0
read 1 : 51
read 0 : 52
read 0 : 106
read 1 : 104
read 0 : 109
read 1 : 162
read 0 : 166
read 1 : 220
read 0 : 225
read 1 : 280
read 0 : 286
read 1 : 342
read 0 : 349
read 1 : 406
read 0 : 414
read 1 : 472
read 0 : 481
read 1 : 540
read 0 : 550
read 1 : 610
read 0 : 621
read 1 : 682
read 0 : 694
read 1 : 756
read 0 : 769
read 1 : 832
read 0 : 846
read 1 : 910
read 0 : 925
read 1 : 990
read 0 : 1006
read 1 : 1072
read 0 : 1089
read 1 : 1156
read 0 : 1174
read 1 : 1242
read 0 : 1261
read 1 : 1330
read 0 : 1350
read 1 : 1420
read 0 : 1441
read 1 : 1512
read 0 : 1534
read 1 : 1606
read 0 : 1629
read 1 : 1702
read 0 : 1726
read 1 : 1800
read 0 : 1825
read 1 : 1900
read 0 : 1926
read 1 : 2002
read 0 : 2029
read 1 : 2106
read 0 : 2134
read 1 : 2212
read 0 : 2241
read 1 : 2320
read 0 : 2350
read 1 : 2430
read 0 : 2461
read 1 : 2542
read 0 : 2574
read 1 : 2656
read 0 : 2689
read 1 : 2772
read 0 : 2806
read 1 : 2890
read 0 : 2925
read 1 : 3010
read 0 : 3046
read 1 : 3132
read 0 : 3169
read 1 : 3256
read 0 : 3294
read 1 : 3382
read 0 : 3421
read 1 : 3510
read 0 : 3550
read 1 : 3640
read 0 : 3681
read 1 : 3772
read 0 : 3814
read 1 : 3906
read 0 : 3949
read 1 : 4042
read 0 : 4086
read 1 : 4180
read 0 : 4225
read 1 : 4320
read 0 : 4366
read 1 : 4462
read 0 : 4509
read 1 : 4606
read 0 : 4654
read 1 : 4752
read 0 : 4801
read 1 : 4900
read 0 : 4950
read 1 : 5050
50

以上结果可以发现,thread 0由0开始跑,thread 1由51开始跑,但之后就随机分配到两个核心,所以充分利用两个核心来运算。

inline assembly:我asm忘了差不多了, 一时也写不出来XD

改用unsigned int,而不用int,这种写法经我测试可以快一倍速度,主要是int须动用到有号数运算,速度较慢,详细原理请参考(原创) 无号数及有号数的乘加运算电路设计 (初级) (IC Design) (Verilog) (Linux)

/*
(C) OOMusou 2007 http://oomusou.cnblogs.com

Filename : for_loop_original.c
Compiler : Visual C++ 8.0
Description : Demo how to optimize for loop
Release : 01/05/2008 1.0
*/

#include <stdio.h>

int foo(int n) {
unsigned int i, s = 0;
for(i = 0; i <= n; i++)
s = s + i;

return s;
}

int main() {
int s;
s = foo(100000000000);
printf("%d\n", s);
}

使用Loop unwinding,请参考Wiki Loop unwinding

/*
(C) OOMusou 2007 http://oomusou.cnblogs.com

Filename : for_loop_unwiding.c
Compiler : Visual C++ 8.0
Description : Demo how to optimize for loop
Release : 01/11/2008 1.0
*/

#include <stdio.h>

int foo(int n) {
unsigned int i, s = 0;
for(i = 1; i <= n; i+=10) {
s += i;
s += i+1;
s += i+2;
s += i+3;
s += i+4;
s += i+5;
s += i+6;
s += i+7;
s += i+8;
s += i+9;
}

return s;
}

int main() {
int s;
s = foo(100);
printf("%d\n", s);
}

使用C++的Template Meta Programming方式,由于这是一种在compile time的运算,而不是在run time计算,所以在run time速度很快。

/*
(C) OOMusou 2007 http://oomusou.cnblogs.com

Filename : for_loop_tmp_cpp.cpp
Compiler : Visual C++ 8.0
Description : Demo how to optimize for loop by TMP
Release : 01/05/2008 1.0
*/

#include <iostream>

using namespace std;

template <unsigned n>
struct foo {
enum { value = n + foo<n-1>::value };
};

template<>
struct foo<0> {
enum { value = 0 };
};

int main() {
cout << foo<100>::value << endl;
}

C++的template类似C的macro,是否可用c来达成呢?我试着用以下的C,但无法compile成功,主要是C并不支持recursive macro,所以无福消受。

1#include <stdio.h>
2#define foo(x) ((x)?((x)+foo(x-1)):(0))
3
4int main() {
5 int s = foo(100);
6 printf("%d\n", s);
7}

7.使用硬件加速编译器;

浅谈嵌入式系统之SOC

嵌入式系统(SOC)算是近几年来相当热门的话题,许多人也纷纷朝这方向研究及分析,不过也有大多数的人不得其门而入,在此小弟简单的介绍一下。
 
要使用SOC之前,我们必须先考虑一个问题,我们所建立的SOC功能为何,目的为何,如果说只是单纯建立几个基本正反器,或者是几个简单的逻辑闸组成的电路,小弟是认为这用硬件描述语言就可以解决,甚至于买块面包板跟IC回来插一插就搞定了,若说用到SOC 有点杀鸡焉用牛刀之感,所以确定自己的需求是相当重要之事。
 
废话不多说 我们赶快进入SOC的话题吧。
 
SOC 顾名思义就是System on Chip,至于要在一颗chip上建立一个system而言,并不是可以用简单的HDL就能处理的,我们先思考几个问题。
 
既然是system 那么是怎样的system?什么样的对象(或硬件)算得上on chip?在system部分分成两部分一个是硬件、一个是软件,在硬件的部份 包含在SOC里面有许多部份。
 
我们以Altera NIOS II的架构来说(如下图)
 
 
在框框里面的即为一嵌入式系统,里头包含了CPU, Bus, On-Chip Memory 等等,这些全是硬件的部份,也就是说要建立一个SOC的最基础,就是要从这里开始。
 
我们可以这样想,在框框外是实体的硬件,也就是真正看得见的chip或硬件(如LED, LCD等等),而要让它们动作,得靠我们所设计的controller或driver,而这方面的设计,可依我们的需求会有所不同,这也是NIOS II最大的特点。
 
另外我们再来看另一个架构--ARM
 
这是一个很典型的ARM系统,我相信应该有人发现了几个问题,首先是系统问题, 似乎ARM的系统远比NIOS II复杂,且架构也比NIOS II大,感觉ARM的功能性比NIOS II强大,那么两者的差别到底在哪里?
 
这个问题的解答正是各家SOC不同的地方,撇开CPU的架构而言,另一个差别就在于BUS,NIOS II的BUS名为Avalon Bus,ARM的为AMBA Bus,而ARM的AMBA又分为两个:AHB和APB。
 
从上图中我们可以发现,AHB主要是掌管内存部分,APB是掌管硬件周边,在两个BUS的双重使用下,可更容易降低CPU的负担,感觉上在这方面似乎NIOS II的BUS逊色不少,但各位也别忘了,NIOS II的优点在于硬件是客制化的(Custom),也就是说,NIOS II也可以实现双BUS架构,因此只要是在FPGA内的LE够的话,想要扩充不是问题。
 
那么ARM是否就没有缺点了呢?这个答案是否定的,ARM的缺点就在于硬件的弹性,在NIOS II里,我们可以依据自己的需求而增加所要的硬件,而在ARM的话,硬件的设计是包好的,也就是说,BUS分成两条就是两条,而我们也不能将APB所连接的组件连到AHB上面,所以在限制上,ARM的硬件弹性比NIOS II低。
 
先前说过,SOC分成两大部分:硬件和软件,刚刚已经稍微介绍了两个平台的硬件,接着我们从软件的角度来分析。
 
首先在NIOS II上面,当硬件架设好后,就是要将软件运行在所设计的硬件上,在NIOS II里所采用的是MicroC/OS-II,而ARM上面的OS则可支持很多,例如uCLINUX, WINCE, VxWork等等,这并不是说NIOS II就不支持,只是在porting上比较复杂。
 
另外一提, 在NIOS II上的OS是要自己规划的,也就是说我们引进了OS的基本函式库后,在什么时间该执行哪个TASK是自行设定,这个设定跟一开始在硬件时的设定有关,所以在使用OS上就显得麻烦了一点,相对于uCLINUX,就有点像是一般安装LINUX,只要针对自己的硬件,给定相对应的参数即可。
 
有了OS,再来谈Application Software,在ARM上面开发软件确实比NIOS II方便,它就像是一台小型的PC,而我们只需要在PC上安装开发软件即可,但在NIOS II上,光是要做一个软件接口就不是十分容易,因此在软件部分, ARM略胜NIOS II一筹。
 
NIOS的优势在于灵活可定置外设,而ARM是把常用的外设都做好了布局布线固化在那里,它可以实现最优化的芯片构架设计。个人认为如果你的嵌入式系统不需要一些纯硬件算法,如FFT,FIR,编解码等,或者硬件平台要经常作变动的,NIOS就不是最好的选择,它体现不了FPGA和SOPC的优势。

 

灵活的外设和硬件算法的实现,这些都是Nios II的优点。不过若以研究来说,Nios II远比ARM有趣,因为软件硬件的功力都需要有,一旦上瘾就很难自拔。

 
说到这里,相信各位应该对SOC有了基本的认识,其实SOC的平台很多,在此虽然只举出两个例子供大家比较,而我们可以在此给两者做个结论,若各位的设计是比较偏向硬件,可选择NIOS II,若是偏向软件,ARM是比较方便,我想这也是为何业界偏好使用ARM来开发商品而不用NIOS II,不过,谁好谁坏,还是看需求为主,这是没有绝对的。
 
但请记得,SOC的主体架构是相同的,差别只在于CPU与BUS的架构,这才是SOC的灵魂,也是主宰SOC效能的最大主因。
 
参考文件:
Nios II Processor Reference Handbook
基于ARM的SOC设计入门

2008年10月22日星期三

(转) 给对电机领域有兴趣的学弟学妹建议

Abstract
假如能重新来过读大一,你会怎么读呢?以下是我对学弟学妹的建议。

Introduction
电机领域很大,有固态电子、IC设计、计算机、通讯、控制、光电、医工...等,由於我有兴趣的是IC设计和计算机,若学弟学妹对此领域有兴趣,我有以下建议:

在大一时,顷全力将C语言和Verilog两个语言搞好,为什么呢?
1.C语言:
这是软体语言的代表,这科影响了后续的资料结构、演算法、计算机组织、作业系统、驱动程式、系统程式、韧体实验、编译器的学习,也就是说只要是软体且要写程式,都逃不掉C语言,C语言没学好,剩下这几科根本学不好。

2.Verilog语言:
这是硬体语言的代表,这科影响了后续的逻辑设计、数位设计、计算机组织、VLSI、SOC、FPGA等科目的学习,当你学这些科目时,若你懂硬体语言,可以直接在code中理解背后的理论,所谓『有code有真相』,而且还能藉由理论自己实作来验证,如在计算机组织学到的pipeline理论,自己可以用Verilog将其实现,这样将更有感觉。

Conclusion
C语言和Verilog语言分别是软体语言和硬体语言的代表,若两个都熟,会帮你同时打通软体和硬体的任督二脉,尤其嵌入式系统的兴起,软体和硬体已经整合,没什么只懂硬体或只懂软体的人才,两个都得懂。大一电机系都会教C语言,只要跟著学校好好学就好(当然我承认C语言很难学),但是通常学校将Verilog或者VHDL放到大二或大三才教,我觉得太晚了,建议学弟学妹大一就自修Verilog,这样大二大三的逻辑设计、数位设计、计算机组织会学得更好,更有感觉,这我有深切的体认。

至於C++呢?我的建议是:『行有余力,再学C++』,毕竟C语言和Verilog的重要性远大於C++,虽然C++的物件导向泛型非常有趣,MFC、Qt、SystemC..等也是用C++,但对於电机系大一而言,C语言和Verilog的重要性远大於C++,所以先将这两科搞好比较重要。

C/C++几点知识

1. 为了节省内存,是否该使用char或short取代int做计算?
很早以前就有这个疑问,在C/C++中,若明知自己的计算没有很大,是否可以char或short来取代int以节省内存。C++ Primer 4th在P.38做了以下的建议:

When performing integer arithmetic, it is rarely right to use shorts. In most programs, using shorts leads to mysterious bugs when a value is assigned to a short that is bigger than the largest number it can hold. What happens depends on the machine, but typically the value "wrap around" so that a number too large to fit turns into a large negative numbers. For the same reason, even though char is an integral type, the char type should be used to hold characters and not for computation. The fact that char is signed on some implementations and unsigned on others makes it problematic to use it as a computational type.

2. 浮点运算时,该使用float还是double?
在C++ Primer 4th P.38,对float和double做了以下的建议
Determining which floating-point type to use is easier: It is almost always right to use double. The loss of precission implicit in float is significant, whereas the cost of double precision calculations versus single precision is negligible. In fact, on some machines, double precision is faster than single.

3. i++和++i哪个速度较快?
++i和i++哪个速度较快呢?在C++ Primer 4th整本书中,都是用++i。为什么,答案是因为++i较快,所以C++ Primer才都使用++i。

++i相当于
i = i + 1;
return i;

而i++相当于
int j = i;
i = i+1;
return j;

由于i++还必须copy值给j,所以速度较慢。

4. include了不必要的Header File,是否会增加编译后程序的大小呢?
编译器会根据您所撰写的程序内容自己到所含括进来的头文件去撷取所需要的信息,而没有使用到的信息则不属于这个程序的范围,故不会增加代码的大小。当然,我们也没有必要含括一些没有必要的头文件到程序来,因为这只会徒增程序阅读的困扰。
参考: C语言教学手册 P2-6,洪维恩著