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设计入门