闲谈x86/x86-64/x64/AMD64/i386/i486/i586/i686

x86与i386/i486/i586/i686等

x86或80×86是英特尔Intel首先开发制造的一种微处理器体系结构的泛称.
该系列较早期的处理器名称是以数字来表示,并以"86"作为结尾,包括Intel 8086/80186/80286/80386以及80486,因此其架构被称为"x86".由于数字并不能作为注册商标,因此Intel及其竞争者均在 新一代处理器使用可注册的名称,如Pentium.现时Intel把x86-32称为IA-32,全名为Intel Architecture, 32-bit.不过由于x86包括16位的处理器,这样的命名也出现麻烦.

x86架构于1978年]推出的Intel 8086中央处理器中首度出现,它是从Intel 8008处理器中发展而来的,而8008则是发展自Intel 4004的.8086在三年后为IBM PC所选用,之后x86便成为了个人计算机的标准平台,成为了历来最成功的CPU架构.
其它公司也有制造x86架构的处理器,计有Cyrix(现为VIA所收购)/NEC集团/IBM/IDT以及Transmeta.Intel以外最成功的制造商为AMD,其Athlon系列处理器的市场仅次于Pentium.
8086是16位处理器;直到1985年32位的80386的开发,这个架构都维持是16位.接着一系列的处理器表示了32位架构的细微改进,推出了数种 的扩充,直到2003年AMD对于这个架构发展了64位的扩充,并命名为AMD64(有时也被称作x86-64,x64或EM64T),推出了 Opteron处理器家族,开创了x86的64位时代.
值得注意的是Intel早在1990年代就与惠普合作提出了一种用在安腾系列处理器中的独立的64位架构,这种架构被称为IA-64.IA-64是一种崭新的系统,和x86架构完全没有相似性;不应该把它与AMD64或x86-64弄混.

x86是一个Intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X与处理器没有任何关系,它是一个对所有*86系统的简单的通配符定义,例如:i386,586,奔腾(pentium).

由于早期intel的CPU编号都是如8086,80286来编号,这整个系列的CPU都是指令兼容的,所以都用X86来标识所使用的指令集合.如今的奔腾/P2/P4/赛扬系列都是支持X86指令系统的,所以都属于X86家族.

x86指令集是美国Intel公司为其第一块16位CPU(i8086)专门开发的.

为了保证电脑能继续运行以往开发的各类应用程序以保护和继承丰富的软件资源,所以Intel公司所生产的所有CPU仍然继续使用X86指令集,所以它的 CPU仍属于X86系列.

另外除Intel公司之外,AMD和Cyrix等厂家也相继生产出能使用X86指令集的CPU,由于这些CPU能运行所有的为Intel CPU所开发的各种软件,所以电脑业内人士就将这些CPU列为Intel的CPU兼容产品.由于Intel X86系列及其兼容CPU都使用X86指令集,所以就形成了今天庞大的X86系列及兼容CPU阵容.当然在目前的台式(便携式)电脑中并不都是使用X86 系列CPU,部分服务器和苹果(Macintosh)机中还使用美国DIGITAL(数字)公司的Alpha 61164和PowerPC 604e系列CPU.

Intel 80×86简称ix86,比如i386/i586/i686等等,指的是适用于intel i386/i586/i686兼容指令集的微处理器.i686应该是P2以上级别的CPU,i586应该是pentium这一系列都可以,但pentium pro 属于i686.

x86-64与x64/AMD64等

"x86-64",有时会简称为"x64",是64位微处理器架构及其相应指令集的一种,也是Intel x86架构的延伸产品."x64"最先由AMD设计,推出时被称为"AMD64",其后也为英特尔所采用,现时英特尔称之为"Intel 64",在之前曾使用过Clackamas Technology (CT)/IA-32e及EM64T.外界多使用"x86-64"或"x64" 去称呼此64位架构,从而保持中立,不偏袒任何厂商.

MyISAM几个容易忽视的配置选项

MyISAM在读操作占主导的情况下是很高效的。可一旦出现大量的读写并发,同InnoDB相比,MyISAM的效率就会直线下降,而且,MyISAM和InnoDB的数据存储方式也有显著不同:通常,在MyISAM里,新数据会被附加到数据文件的结尾,可如果时常做一些UPDATE,DELETE操作之后,数据文件就不再是连续的,形象一点来说,就是数据文件里出现了很多洞洞,此时再插入新数据时,按缺省设置会先看这些洞洞的大小是否可以容纳下新数据,如果可以,则直接把新数据保存到洞洞里,反之,则把新数据保存到数据文件的结尾。之所以这样做是为了减少数据文件的大小,降低文件碎片的产生。但InnoDB里则不是这样,在InnoDB里,由于主键是cluster的,所以,数据文件始终是按照主键排序的,如果使用自增ID做主键,则新数据始终是位于数据文件的结尾。

了解了这些基础知识,下面说说MyISAM几个容易忽视的配置选项:

concurrent_insert:

通常来说,在MyISAM里读写操作是串行的,但当对同一个表进行查询和插入操作时,为了降低锁竞争的频率,根据concurrent_insert的设置,MyISAM是可以并行处理查询和插入的:

当concurrent_insert=0时,不允许并发插入功能。
当concurrent_insert=1时,允许对没有洞洞的表使用并发插入,新数据位于数据文件结尾(缺省)。
当concurrent_insert=2时,不管表有没有洞洞,都允许在数据文件结尾并发插入。

这样看来,把concurrent_insert设置为2是很划算的,至于由此产生的文件碎片,可以定期使用OPTIMIZE TABLE语法优化。

max_write_lock_count:

缺省情况下,写操作的优先级要高于读操作的优先级,即便是先发送的读请求,后发送的写请求,此时也会优先处理写请求,然后再处理读请求。这就造成一个问题:一旦我发出若干个写请求,就会堵塞所有的读请求,直到写请求全都处理完,才有机会处理读请求。此时可以考虑使用max_write_lock_count:

max_write_lock_count=1

有了这样的设置,当系统处理一个写操作后,就会暂停写操作,给读操作执行的机会。

low-priority-updates:

我们还可以更干脆点,直接降低写操作的优先级,给读操作更高的优先级。

low-priority-updates=1

综合来看,concurrent_insert=2是绝对推荐的,至于max_write_lock_count=1和low-priority-updates=1,则视情况而定,如果可以降低写操作的优先级,则使用low-priority-updates=1,否则使用max_write_lock_count=1。

MySQL性能优化技巧

打开/etc/my.cnf文件,修改以下设置,如果没有,可手动添加。调整设置时,请量力而行,这与你的服务器的配置有关,特别是内存大小。以下设置比较适合于1-2G内存的服务器,但并不绝对。

back_log = 200

要求MySQL能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增加它,换句话说,这值对到来的TCP/IP连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定back_log高于你的操作系统的限制将是无效的。默认数值是50

max_allowed_packet = 4M

一个包的最大尺寸。消息缓冲区被初始化为net_buffer_length字节,但是可在需要时增加到max_allowed_packet个字节。缺省地,该值太小必能捕捉大的(可能错误)包。如果你正在使用大的BLOB列,你必须增加该值。它应该象你想要使用的最大BLOB的那么大。

max_connections = 1024

max_used_connections / max_connections ≈ 85%

允许的同时客户的数量。增加该值增加 mysqld要求的文件描述符的数量。这个数字应该增加,否则,你将经常看到 链接过多,请联系空间商 错误。 默认数值是100

table_open_cache = 512

open_tables / opened_tables >= 85%
open_tables / table_open_cache <= 95%

指定表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。检查峰值时间的状态值,如果open_tables等于table_open_cache,并且opened_tables在不断增长,那么就需要增加table_open_cache的值。注意,不能盲目地把table_open_cache设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。

tmp_table_size = 64M
max_heap_table_size = 32M

created_tmp_disk_tables / created_tmp_tables <= 25%

当临时内存表的大小达到一定限制的时候,MySQL就会将临时内存表写入到磁盘,变为临时磁盘表。这个限制由 tmp_table_size 和 max_heap_table_size 这两个变量中的最小值确定。

key_buffer = 384M

指定索引缓冲区的大小,它决定索引处理的速度,尤其是索引读的速度。通过检查状态值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。

比例key_reads/key_read_requests应该尽可能的低,至少是1:100,1:1000更好。在专有的数据库服务器上,该值可设置为 RAM * 1/4。

key_buffer_size只对MyISAM表起作用。即使你不使用MyISAM表,但是内部的临时磁盘表是MyISAM表,也要使用该值。可以使用检查状态值created_tmp_disk_tables得知详情。

sort_buffer_size = 4M

每个线程排序所需的缓冲。如果状态值sort_merge_passes(排序算法使用归并的次数)很大,则应该把sort_buffer_size的值变大。

read_buffer_size = 4M

当一个查询不断地扫描某一个表,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果你认为连续扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。

表扫描率 = handler_read_rnd_next / com_select
如果表扫描率超过 4000,说明进行了太多表扫描,很有可能索引没有建好,增加 read_buffer_size 值会有一些好处,但最好不要超过8mb。

read_rnd_buffer_size = 8M

加速排序操作后的读数据,提高读分类行的速度。如果正对远远大于可用内存的表执行GROUP BY或ORDER BY操作,应增加read_rnd_buffer_size的值以加速排序操作后面的行读取。仍然不明白这个选项的用处……

thread_cache_size = 128

可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性能可以这个变量值。如果threads_created/connections很大,则应该把thread_cache_size的值变大。

query_cache_size = 32M

查询结果缓存。第一次执行某条SELECT语句的时候,服务器记住该查询的文本内容和它返回的结果。服务器下一次碰到这个语句的时候,它不会再次执行该语句。作为代替,它直接从查询缓存中的得到结果并把结果返回给客户端。

thread_concurrency = 2

最大并发线程数,cpu数量*2

wait_timeout = 120

设置超时时间,能避免长连接

skip-innodb
skip-bdb

关闭不需要的表类型,如果你需要,就不要加上这个

MySQL5.6参数变化:

http://dev.mysql.com/doc/refman/5.6/en/server-default-changes.html

相关说法:
1、handler_read_rnd 根据固定位置读取行的请求数。如果你执行很多需要排序的查询,该值会很高。你可能有很多需要完整表扫描的查询,或者你使用了不正确的索引用来多表查询。
2、handler_read_rnd_next 从数据文件中读取行的请求数。如果你在扫描很多表,该值会很大。通常情况下这意味着你的表没有做好索引,或者你的查询语句没有使用好索引字段。
3、table_locks_waited 无法立即获得锁定表而必须等待的次数。如果该值很高,且您遇到了性能方面的问题,则应该首先检查您的查询语句,然后使用复制操作来分开表。如果 table_locks_immediate / table_locks_waited > 5000,最好采用innodb引擎,因为innodb是行锁而myisam是表锁,对于高并发写入的应用innodb效果会好些。

扩展阅读:
有人提起过依据key_reads/key_read_requests调整key_buffer_size有失偏颇,如果感兴趣,不妨移步这里看看:http://www.baidu.com/s?wd=key_reads+%2f+uptime

让IE6-7兼容CSS的inline-block

在IE6、IE7中不识别display:inline-block属性,但使用inline-block属性在IE下会触发layout,从而使内联元素拥有了display:inline-block属性的表症。从上面的分析也不难理解为什么IE6、IE7下对块元素设置display:inline-block属性无法实现inline-block的效果。这时块元素仅仅是被inline-block触发了layout,而它本就是行布局,所以触发后,块元素依然是行布局。IE8识别display:inline-block;

在IE6、IE7中实现块元素的inline-block效果有以下两种方法:

1.先使用display:inline-block属性触发layout,然后再定义display:inline让块元素呈现内联对象(两个display要先后放在两个CSS声明中才有效果,这是IE的一个经典BUG)。

2.直接将块元素设置为display:inline呈现为内联对象,然后触发layout(如zoom:1)。

<html>
<head>
<style type="text/css">
.box{width:100px;height:100px;border:1px solid #FF7900;margin:8px;}
.ib1{display:inline-block;}
.ib1{*display:inline;}
.ib2{display:inline-block;*display:inline;*zoom:1;}
</style>
</head>
<body>
<div class="box ib1">1</div><div class="box ib1">2</div>
<div class="box ib2">3</div><div class="box ib2">4</div>
</body>
</html>

在Ubuntu下编译CyanogenMod7

经常要从CM7源代码构建ROM,于是以Atrix4G为例写了这个脚本,实现自动编译新版CM7。
当然,脚本可能还有一些不完善的地方,欢迎大家提出来。

#!/bin/sh
#
# 编译环境 Ubuntu Desktop 11.10
# 参考文献 http://www.anrip.com/post/261
# http://developer.android.com/sdk/installing.html
# http://source.android.com/source/initializing.html
# http://wiki.cyanogenmod.com/wiki/Motorola_Droid:_Compile_CyanogenMod_%28Linux%29
#

sudo su -
ulimit -S -n 1024

# 设定工作目录
export WORK=/media/workspace
export PATH=$PATH:$WORK/bin
mkdir -p $WORK/CyanogenMod
mkdir -p $WORK/bin

# 安装必要的软件包
apt-get install git-core zip curl gnupg flex bison \
  gperf pngcrush schedtool build-essential squashfs-tools \
  libsdl1.2-dev libesd0-dev libwxgtk2.6-dev libncurses5-dev zlib1g-dev

# 安装其他软件包
if [ $(getconf LONG_BIT) == 64 ]; then
  apt-get install lib32z1-dev lib32ncurses5-dev lib32readline5-dev g++-multilib
fi

# 安装java-sdk
apt-get install openjdk-6-jdk

# 安装android-sdk
cd $WORK/
wget http://dl.google.com/android/android-sdk_r14-linux.tgz
tar xvf android-sdk_r14-linux.tgz && rm android-sdk_r14-linux.tgz

# 手动选择并安装platform-tools
$WORK/android-sdk-linux/tools/android
export PATH=$PATH:$WORK/android-sdk-linux/platform-tools

# 安装repo工具
cd $WORK/bin/
wget https://dl-ssl.google.com/dl/googlesource/git-repo/repo
chmod 0755 repo

# 同步CM7源码
cd $WORK/source/
repo init -u git://github.com/source/android.git -b gingerbread
repo sync -j16

# 把编译选项-m64改成-m32
cd $WORK/source/external/clearsilver/
if [ $(getconf LONG_BIT) == 32 ]; then
  sed -i "s/-m64/-m32/g" cgi/Android.mk
  sed -i "s/-m64/-m32/g" cs/Android.mk
  sed -i "s/-m64/-m32/g" java-jni/Android.mk
  sed -i "s/-m64/-m32/g" util/Android.mk
fi

# 获取设备专属文件(需调试模式连接手机)
cd $WORK/source/device/motorola/olympus/
./extract-files.sh

# 下载Rom管理器
cd $WORK/source/vendor/cyanogen/
./get-rommanager

# 编译CM7源码
cd $WORK/source/
source build/envsetup.sh
brunch olympus

PHP获取腾讯QQ在线状态

想要自定义QQ在线图标,关键是要获取到QQ在线状态,为此写了如下函数以获取QQ在线状态。
我给出了4种状态,其实一般只需要判断是否在线(1/2)就可以,另外2种状态(0/3)用于调试。

此函数通过腾讯的两个接口判断,一定程度上增加了判断的稳定性。

注意:此函数需要服务支持file_get_contents读取URL。

/*!
 * 获取腾讯QQ在线状态
 * @param int $uin 腾讯QQ号码
 * @return int [0:服务器错误,1:离线或隐身,2:在线,3:异常]
 */
function get_qq_status($uin) {
  if($uin > 9999) {
    error_reporting(0);
    $data = file_get_contents("http://webpresence.qq.com/getonline?type=1&{$uin}:");
    $data || $data = strlen(file_get_contents("http://wpa.qq.com/pa?p=2:{$uin}:45"));
    if(!$data) { return 0; }
    switch((string)$data) {
      case '854': case 'online[0]=0;': return 1;
      case '834': case 'online[0]=1;': return 2;
    }
  }
  return 3;
}

JavaScript获取浏览器Flash版本

/*!
 * 获取浏览器Flash版本号
 */
function get_flash_version() {
  var SF, FV = 0, BR = window.navigator;
  if(BR.plugins && BR.mimeTypes.length) {
    SF = BR.plugins["Shockwave Flash"];
    if(SF && SF.description) {
      FV = SF.description.replace(/[^\d\.]/g,"").split(".")[0];
    }
  } else if(BR = window.ActiveXObject) {
    try {
      SF = new BR("ShockwaveFlash.ShockwaveFlash.7");
      FV = SF.GetVariable("$version").split(" ")[1].split(",")[0];
    } catch(e) {}
  }
  return +FV;
}

Ubuntu下搜索文件和文件内容

查找软件的安装路径

whereis < 程序名称>
-b 只查找二进制文件
-m 只查找帮助文件
-s 只查找源代码
-u 排除指定类型文件
-f 只显示文件名
-B < 目录> 在指定目录下查找二进制文件
-M < 目录> 在指定目录下查找帮助文件
-S < 目录> 在指定目录下查找源代码

在文件索引数据库中搜索文件

locate < 文件名称>
-d < 数据库路径> 搜索指定数据库
updatedb 更新文件索引数据库

查找文件

find [路径] < 表达式>
-name < 表达式> 根据文件名查找文件
-iname < 表达式> 根据文件名查找文件,忽略大小写
-path < 表达式> 根据路径查找文件
-ipath < 表达式> 根据路径查找文件,忽略大小写
-amin < 分钟> 过去N分钟内访问过的文件
-atime < 天数> 过去N天内访问过的文件
-cmin < 分钟> 过去N分钟内修改过的文件
-ctime < 天数> 过去N天内修改过的文件
-anewer < 参照文件> 比参照文件更晚被读取过的文件
-cnewer < 参照文件> 比参照文件更晚被修改过的文件
-size < 大小> 根据文件大小查找文件,单位b c w k M G
-type < 文件类型> 根据文件类型查找文件。b 块设备 c 字符设备 d 目录 p 管道文件 f 普通文件 l 链接 s 端口文件
-user < 用户名> 按归属用户查找文件
-uid 按UID查找文件
-group < 群组名> 按归属群组查找文件
-gid 按GID查找文件
-empty 查找空文件

批处理检测是否已安装VC2008运行库

在做iServer批处理版控制台时写了2种方法,测试环境WindowsXP/2003/Vista/7(x86)。这里给出来,供大家参考:

方法一:
这只是简单的检测,并不保证运行库完整可靠性,至于检测其他版本的运行库,可以修改find后面的字符串来实现。

@echo off
echo. && echo 测试VC++运行库...
dir %windir%\WinSxS | find /i /c "Microsoft.VC90" >nul || (
  echo 测试失败,尚未安装VC++2008
)
pause

方法二:
通过注册表搜索已注册的卸载信息来获取安装状态,相对比较准确,只是对微软更新比较敏感,需要随时更新注册信息。

@echo off
set "HKLMU=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
reg query %HKLMU%{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 Redistributable X86
reg query %HKLMU%{9A25302D-30C0-39D9-BD6F-21E6EC160475} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable X86
reg query %HKLMU%{1F1C2DFC-2D24-3E06-BCB8-725134ADF989} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable ATL Security Update X86
reg query %HKLMU%{350AA351-21FA-3270-8B7A-835434E766AD} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 Redistributable X64
reg query %HKLMU%{8220EEFE-38CD-377E-8595-13398D740ACE} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable X64
reg query %HKLMU%{4B6C7001-C7D6-3710-913E-5BC23FCE91E6} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable ATL Security Update X64
reg query %HKLMU%{2B547B43-DB50-3139-9EBE-37D419E0F5FA} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 Redistributable IA64
reg query %HKLMU%{5827ECE1-AEB0-328E-B813-6FC68622C1F9} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable IA64
reg query %HKLMU%{977AD349-C2A8-39DD-9273-285C08987C7B} >nul 2>nul && set VC2008=Microsoft Visual C++ 2008 SP1 Redistributable ATL Security Update IA64
if defined VC2008 (
  echo 已安装 %VC2008%
) else (
  echo 未安装 VC2008
)
pause