<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>VC爱好者 v3.0</title>
	<atom:link href="http://www.vcfans.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.vcfans.com</link>
	<description>生活的天平本不平衡，只有通过努力改变其偏向。</description>
	<lastBuildDate>Tue, 22 Nov 2011 17:32:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>OpenGL ES glTexSubImage2D返回GL_INVALID_OPERATION</title>
		<link>http://www.vcfans.com/2011/10/opengl-es-gltexsubimage2d-gl-invalid-operation.html</link>
		<comments>http://www.vcfans.com/2011/10/opengl-es-gltexsubimage2d-gl-invalid-operation.html#comments</comments>
		<pubDate>Thu, 27 Oct 2011 14:50:17 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[编程开发]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1548</guid>
		<description><![CDATA[Xcode升级成4.2正式版后，使用IOS5.0的SDK，以前一直真机与模拟器都正常的程序。发现在真机正常，模拟器发现不能正常显示。很长见模拟器正常，真机出问题的，没想到这次正好反了。想找出其中的原因，GL的初始化应该没什么好说的，在render处逐条语句glGetError,在glTexSubImage2D是返回GL_INVALID_OPERATION错误，百思不得其解。

根据文档中的说法引起GL_INVALID_OPERATION错误的不外乎这几种原因:
<ol>
	<li>GL_INVALID_OPERATION is generated if the texture array has not been defined by a previous glTexImage2D or glCopyTexImage2D operation.</li>
	<li><code id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown">GL_INVALID_OPERATION</code> is generated if <code><var>type</var></code> is <code>GL_UNSIGNED_SHORT_5_6_5</code> and <code><var>format</var></code> is not <code>GL_RGB</code></li>
	<li><code id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown">GL_INVALID_OPERATION</code> is generated if <code><var>type</var></code> is one of <code>GL_UNSIGNED_SHORT_4_4_4_4</code>, or <code>GL_UNSIGNED_SHORT_5_5_5_1</code> and format is not <code>GL_RGBA</code>.</li>
</ol>
上面，那几种情况我都不太像，很悲情。

这种用法应该没有什么太大问题，但就是不能正常显示。另外新写个Demo程序可以正常显示贴图。然后逐步Demo中对工程对比排查，最终原因是glTexImage2D生成材质是的type指定了GL_RGBA，而在glTexSubImage2D时由于BMP格式的数据，使用了GL_BGRA，导致显示不了。相当悲情的是，以前写的时候居然可以正常运行，这次升级SDK后，才爆露出问题，不过幸好真机正常。

开发是一门严谨的活，来不了半点差错，不能麻痹大意。遇到棘手的问题，将问题抽取出来缩小范围，一点一点的排除，速度不要求快，保证每一步不出错就可以，总能定位出问题的。]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/10/opengl-es-gltexsubimage2d-gl-invalid-operation.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>TinyUmbrella备份SHSH,找不到设备时处理方法。</title>
		<link>http://www.vcfans.com/2011/10/tinyumbrella-backup-shsh-cannot-display-devices.html</link>
		<comments>http://www.vcfans.com/2011/10/tinyumbrella-backup-shsh-cannot-display-devices.html#comments</comments>
		<pubDate>Mon, 17 Oct 2011 17:15:00 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站原创]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[奇技淫巧]]></category>
		<category><![CDATA[教程]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1535</guid>
		<description><![CDATA[使用TinyUmbrella来备份SHSH时，怎么也找不到设备列表，搞的很无耐。可以使用TinyUmbrella的手动模式，处理此问题。

TinyUmbrella模式需要输入ECID.手动获取ECID需要分两步，第一步，进入RecoveryMode,第二步通过USBView查看ECID.

一.进入RecoveryMode。

1.使用数据线，连接Itunes和IPAD。

2.长按“关机键”和“Home键”，进入Recovery Mode.

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1349-500.png"><img class="alignnone size-full wp-image-1536" title="1349-500" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1349-500.png" alt="" width="500" height="127" />
</a>

3.此时屏幕会变成黑屏，松开“关机键”，继续长按“Home键”。只到Itunes弹出如下界面：

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1351-500.png"><img class="alignnone size-full wp-image-1537" title="1351-500" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1351-500.png" alt="" width="500" height="204" /></a>

&#160;

IPAD屏幕将显示如下：

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1352.png"><img class="alignnone size-full wp-image-1538" title="1352" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/1352.png" alt="" width="133" height="250" /></a>

松开“Home键”，至此已经进入Recovery Mode了。

二、通过Usbview查看ECID。

1.启动Usbview.

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/31945-500.png"><img class="alignnone size-full wp-image-1539" title="31945-500" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/31945-500.png" alt="" width="500" height="358" /></a>

2.通过“File”菜单中的"Refesh"按钮，列取USB设备。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/31948-500.png"><img class="alignnone size-full wp-image-1540" title="31948-500" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/10/31948-500.png" alt="" width="500" height="227" /></a>
在左侧列表中找到相应的IPAD设备，选中将会在右侧显示，详细的设备信息。在一串字符中找到十六进制的ECID.

最后将这个ECID输入到TinyUmberlla中，即可取得几个版本的SHSH了。

下载UsbView: [download id="116"]]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/10/tinyumbrella-backup-shsh-cannot-display-devices.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>乔帮主走了</title>
		<link>http://www.vcfans.com/2011/10/steven-jobs-died.html</link>
		<comments>http://www.vcfans.com/2011/10/steven-jobs-died.html#comments</comments>
		<pubDate>Fri, 07 Oct 2011 15:52:18 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站杂谈]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1533</guid>
		<description><![CDATA[七天没碰电脑没有接触网络，回来收到的第一条消息是乔布斯去世。这虽然是迟早的事，但这一天还是到来了。看看乔帮主的一生，有着无数个传奇，神一般的人物。从03年查出癌症后，这八年中苹果出的这些产品，真的太惊人了。根本不能相信这是一个生命垂危之人，带领团队做出来的。

乔帮主，绝对是个传说。

一路走好，希望库克能继续把苹果带好。]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/10/steven-jobs-died.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn Vim Progressively</title>
		<link>http://www.vcfans.com/2011/09/learn-vim-progressively.html</link>
		<comments>http://www.vcfans.com/2011/09/learn-vim-progressively.html#comments</comments>
		<pubDate>Tue, 13 Sep 2011 16:50:25 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[文档资料]]></category>
		<category><![CDATA[VIM]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1530</guid>
		<description><![CDATA[老外的教程真的没得说，<a href="http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/">http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/</a>。]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/09/learn-vim-progressively.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>i386 Addressing Modes and Assembler Instructions</title>
		<link>http://www.vcfans.com/2011/08/i386-addressing-modes-and-assembler-instructions.html</link>
		<comments>http://www.vcfans.com/2011/08/i386-addressing-modes-and-assembler-instructions.html#comments</comments>
		<pubDate>Tue, 30 Aug 2011 02:20:38 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[文档资料]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1527</guid>
		<description><![CDATA[ISO汇编文档:<a href="http://developer.apple.com/library/mac/#documentation/DeveloperTools/Reference/Assembler/060-i386_Addressing_Modes_and_Assembler_Instructions/i386_intructions.html#//apple_ref/doc/uid/TP30000825-TPXREF101">查看原文</a>]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/08/i386-addressing-modes-and-assembler-instructions.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Objective-C Programming Language</title>
		<link>http://www.vcfans.com/2011/08/the-objective-c-programming-language.html</link>
		<comments>http://www.vcfans.com/2011/08/the-objective-c-programming-language.html#comments</comments>
		<pubDate>Thu, 25 Aug 2011 02:44:51 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[文档资料]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1518</guid>
		<description><![CDATA[<a href="http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf">下载PDF</a>]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/08/the-objective-c-programming-language.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Arm Neon intrinsics</title>
		<link>http://www.vcfans.com/2011/08/arm-neon-intrinsics.html</link>
		<comments>http://www.vcfans.com/2011/08/arm-neon-intrinsics.html#comments</comments>
		<pubDate>Tue, 23 Aug 2011 05:27:11 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[编程开发]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[嵌入式]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1522</guid>
		<description><![CDATA[Comefrom: <a href="http://monkeystylegames.com/?p=82">monkeystylegames.com/?p=82</a>

The ARMv7 CPU (Cortex-A8) used in the iPhone 3GS is a very nice CPU. One of the things it can do is real SIMD intrinsics. Although Apple don’t document this, the fine folks who made GCC do.

Here’s how to demonstrate this on Xcode.

0. Create a project.

1. Set Target-&#62;Architecture to “Optimized (armv6 armv7)”

This builds a fat binary with two executables – one for the older arm architecture and one for the Cortex/NEON architecture.

2. Set Other C Flags to “-mfloat-abi=softfp -mfpu=neon”.

As specified in the “arm_neon.h” header. I’m guessing that these are ignored for the armv6 binary.

3. Include preprocessor guards in the source to make sure the intrinsics are only compiled in for armv7. See the following snippet:
<pre lang="c" line="1" file="download.txt" colla="+">
#ifdef _ARM_ARCH_7
#include <arm_neon.h>
float32x4_t scale( float32x4_t v, float f )
{
  return vmulq_n_f32( v, f );
}
#endif</pre>
Note: At the moment I can only make this code compile under C, there seems to be an internal GCC issue when compiling this code as C++

4. Choose “Build-&#62;Show Assembly Code”. You should see a “vmul.f32    x,  y, z” assembly instruction buried amongst the stack maintenance code.

Good news for mobile gamers. NEON, together with proper shaders, should help the next wave of iPhone games leapfrog the quality of other handhelds.]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/08/arm-neon-intrinsics.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenGL ES Programming Guide for iOS</title>
		<link>http://www.vcfans.com/2011/08/opengl-es-programming-guide-for-ios.html</link>
		<comments>http://www.vcfans.com/2011/08/opengl-es-programming-guide-for-ios.html#comments</comments>
		<pubDate>Mon, 22 Aug 2011 15:27:45 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[编程开发]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1519</guid>
		<description><![CDATA[一份OpenGL ES for IOS的英文文档，来自苹果官方。

在线版参见这里：<a href="http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008793-CH1-SW1">查看原文</a>

[download id="115"]]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/08/opengl-es-programming-guide-for-ios.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introduction to NEON on iPhone zz</title>
		<link>http://www.vcfans.com/2011/08/introduction-to-neon-on-iphone-zz.html</link>
		<comments>http://www.vcfans.com/2011/08/introduction-to-neon-on-iphone-zz.html#comments</comments>
		<pubDate>Mon, 22 Aug 2011 14:00:10 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[编程开发]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[嵌入式]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1515</guid>
		<description><![CDATA[<p id="">ComeFrom:<a href="http://wanderingcoder.net/2010/06/02/intro-neon/">http://wanderingcoder.net/2010/06/02/intro-neon/</a></p>
A sometimes overlooked addition to the iPhone platform that debuted with the iPhone 3GS is the presence of an SIMD engine called NEON. Just like AltiVec for PowerPC and MMX/SSE for x86, this allows multiple computations to be performed at once on ARM, giving an important speedup to some algorithms, on condition that the developer specifically codes for it.
<p id="">Given that, among the iPhone OS devices, only the iPhone 3GS and the third-gen iPod Touch featured NEON up until recently, it typically wasn’t worth the effort to work on a NEON optimization since it would benefit only these devices, unless the application could require running on one of them (e.g. because its purpose is to processes videos recorded by the iPhone 3GS). However, with the arrival of the iPad it makes much more sense to develop NEON optimizations. In this post I’ll try to give you a primer on NEON.</p>

<h3>Before we begin, a bit of setup</h3>
This instruction set extension is actually called Advanced SIMD, it is an optional extension to the ARMv7-A profile; however, when ARMv7 is mentioned the presence of the Advanced SIMD extensions is generally implied, unless mentioned otherwise. “NEON” actually refers to the implementation of this extension in ARM processors, but this name is commonly used to designate these SIMD instructions as well as the processor feature.

So far, Apple has only shipped one processor core featuring NEON: the Cortex A8, in three devices: the iPhone 3GS, the third-gen iPod Touch, and the iPad. This means that besides the general details of NEON that are valid whichever the implementation, the details of NEON as implemented in the <a href="http://infocenter.arm.com/help/topic/com.arm.doc.ddi0344j/index.html">Cortex A8</a> are of high interest to us since it’s the only processor core which will run iPhone OS NEON-optimized code at the moment.
<h4>Do You Need It?</h4>
iPhone OS devices (even the iPad) are pretty focused. The user is unlikely to want to perform scientific calculations, simulation, offline rendering, etc. on these devices, so the main applications for NEON here are multimedia and gaming. Then, see if the work hasn’t already been done for you in the Accelerate framework, <a href="http://developer.apple.com/technologies/iphone/whats-new.html#api">new in iPhone OS 4.0</a>, for you to use when the update lands. However, iPhone OS 4.0 won’t make it to the iPad until this fall, and of course if the algorithm you need isn’t in Accelerate, it’s not going to be of any help to you; in these cases, then it makes sense to write your own NEON code.

As always when optimizing, make sure you don’t optimize the wrong thing. When doing multimedia work, hunches about what is taking up processor time are less likely to be wrong than for general applicative work, but you should still first write the regular C version of the algorithm, then profile your code using Shark, in order to know the one part which is taking up the most time, and consequently is to be tackled first (and then the second most, etc.). Then benchmark your improvements to make sure you did improve things (It’s unlikely for the NEON version to be slower than scalar code, but regressions can happen when trying to improve the NEON code).
<h4>Detection and Selection</h4>
Obviously, devices earlier than the iPhone 3GS are not going to be able to run NEON code, so there needs to be a way to select a different code path depending on which device is executing the code; even if you only target, say, the iPad, there needs to be a way to let it be know the code requires NEON, so that it does not accidentally run on a non-NEON device.
<p id="">This way is to build the application for both ARMv6 and ARMv7 (Optimized setting in Xcode), and, using #ifdefs, disable at compile time the undesired code (the NEON code when building for ARMv6, the non-NEON fallback when building for ARMv7; __ARM_NEON__ will be defined if NEON is available); if you target only ARMv7 devices, then only build for ARMv7 (in that case, don’t forget to add armv7 in the <a href="http://developer.apple.com/iphone/library/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW3">UIRequiredDeviceCapabilities</a> of your Info.plist). When your application is run, the device will automatically pick the most capable half it can: the ARMv7/NEON one for ARMv7-capable devices, the ARMv6 half, if present, otherwise. The drawback is that, unless you target only ARMv7 devices, the whole application code size (not just the code for which there is a NEON version) will end up twice in the final distribution: once compiled for ARMv6, and once for ARMv7. As executable code is typically a small portion of the application size, this is not a problem for most applications, but it is a problem for some of them.<sup><a name="fnr-intro-neon-cut"></a><a href="http://wanderingcoder.net/2010/06/02/intro-neon/#fn-intro-neon-cut">1</a></sup></p>
Don’t forget that you’ll need to disable the NEON code at compile time when building for the simulator, as your application is compiled for x86 when targeting the simulator, and NEON code will cause build errors in this context. This means you always need to also write a generic C version of the algorithm, even if you only target the iPad, or you won’t be able to run your application in the simulator.
<h4>Development</h4>
There are actually different ways you can create NEON code. You can program directly in assembly language; it does require good knowledge of ARM assembly programming, so it’s not for everyone, but NEON programming isn’t for everyone, either. You can also remain in C and use compiler intrinsics (which you get by including arm_neon.h), leaving the compiler to worry about register allocation, assembly language details, etc.

ARM mentions a third way, which is to let the compiler auto-vectorize, but I don’t know how well it works, or if it is even enabled in the iPhone toolchain, so I’m not going to reference it here.

I’ve only used assembly programming so far, so I will generally describe techniques under assembly terms, but everything should be equally applicable when programming with intrinsics, just with a different syntax. There is one important thing, however, which is applicable only when you program in assembly (you don’t have to worry about that when using intrinsics): make sure you save and restore d8 to d15 if you use them in your function, as <a href="http://developer.apple.com/iphone/library/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html#//apple_ref/doc/uid/TP40009021-SW1">the ABI</a> specifies that these registers must be preserved by function calls. If you don’t, it may work fine for a while, until you realize with horror that the floating-point variables in the calling functions become corrupted, and all hell breaks loose. So make sure these registers are saved and restored if they are used.
<h3>Architecture Overview</h3>
Now we get to the meat of the matter. To follow from home you will need the architecture document from ARM describing these instructions; fortunately, you already have it. You see, Shark has this feature where you can get help on a particular assembler instruction, which it provides simply by opening the architecture specification document at the page for this instruction. While for PowerPC and Intel, the document bundled with Shark is a simple list of all the instructions, for ARM it is actually a fairly complete subset of the ARM Architecture Reference Manual (some obsolete information is omitted). Rather than open it through Shark, you can open it directly in Preview by finding the helper application (normally at /Library/Application Support/Shark/Helpers/ARM Help.app), right clicking-&#62;Show Package Contents, and locating the PDF in the resources.

I will sometimes reference AltiVec and/or SSE, as these are the SIMD instruction set extensions that iPhone developers are most likely to be familiar with, and there is already an important body of information for both architectures online; less so for NEON.
<h4>Programmer Model</h4>
As you know, SIMD (Single Instruction Multiple Data) architectures apply the same operation (multiplication, shift, etc.) in parallel to a number of elements; the range of elements to which an operation is applied is called a vector. In modern SIMD architectures, vectors have a constant size in number of bits, and contain a different number of elements depending on the element size being operated on: for instance, in both AltiVec and SSE vectors are 128 bits, if the operation is on 8-bit elements for instance, then it operates on 16 elements in parallel (128/8); if the operation is on 16-bit elements, then each vector contains 8 of them (128/16).

In NEON you have access to sixteen 128-bit vector registers, named q0 to q15; this is the same vector size as AltiVec and SSE, and there are twice as many registers as 32-bit SSE, but half as many as AltiVec. However, this register file of 16 Q (for Quadword) vectors can also be seen as thirty-two 64-bit D (Doubleword) vectors, named d0 to d31: each D register is one half, either the low or high one, of a Q register, and conversely each Q register is made up of two D registers; for instance, d12 is the low half of q6, and q3 is at the same location as the d6-d7 pair. Most instructions that do not change the element size between input and output can operate on either D or Q registers; instructions that narrow elements as part of their operation (e.g. a 16-bit element on input becomes a 8-bit element on output) take Q vectors as input and have a D vector as output; instructions that enlarge elements as part of their operation take D vectors as input and have a Q vector as output. There are, however, a few instructions that only work on D vectors: the vector loads, vector stores, vpadd, vpmax, vpmin, and vtbl/vtbx; while for some operations this matters very little (e.g. to load two Q vectors, you use a load multiple instruction with a list containing the four matching D vectors), in the other cases this means the operation must be done in two steps to operate on a Q vector, once on the lower D half and once one the higher D half.

This D/Q duality provides a consistent way to handle narrowing and widening operations, instead of the somewhat ad hoc schemes used by AltiVec and SSE (e.g. for full precision multiplies on AltiVec you multiply the even elements, then the odd elements of a vector; on SSE you obtain the low part of the multiplication, then the high part). It also makes it easier to manage the narrowed vector prior to an operation that uses one, or after an operation that produces one. It does make it a bit tricky to ensure that you don’t overwrite data you want to keep, as you must remember not to use q10 if you want to keep the data in d20.

The register file is shared with the floating-point unit, but NEON and floating-point instructions can be freely intermixed (provided, of course, that you share the registers correctly), contrary to MMX/x87.

A reminder: the ARM architecture (at least as used in the iPhone) is little-endian; remember that when permuting or otherwise manipulating the vector elements.
<h4>Architectural features</h4>
NEON instructions typically have two input and one separate output register, so calculations are generally non-destructive. There are three-operand instructions like multiply-add, but in that case there is no separate output register, in the case of multiply-add for instance the addition input register is also the output. A bit less usual is the fact some instructions, like vzip, have two output registers.

Some instructions take a list of registers. It must be a list of consecutive D registers, though in some cases there can be a delta of two between registers (e.g. {d13, d15, d17}), in order to support data in Q registers.

Some instructions can take a scalar as one of their inputs. In that case, the scalar is used for all operations instead of having the corresponding elements of the two vectors be matched. For instance, if the vector containing a, b, c, d is multiplied by the scalar k, then the result is k×a, k×d, k×c, k×d. Scalars can also be duplicated to all elements of a vector, in preparation for operations that do not support scalar operands. Scalars are specified by the syntax dn[x], where x is the index of the scalar in the dn vector.
<h4>Syntax</h4>
All NEON instructions, even loads and stores, begin by “V”, which makes them easy to tell apart, and easy to locate in the architecture documentation. Instructions can have one (or more) letter just after the V which acts as a modifier: for instance “Q” means the instruction saturates, “R” that it rounds, and “H” that it halves. Not all combinations are possible (far from it), but this gives you an indication when reading the instruction of what it does.

Practically all instructions need to take a suffix telling the individual size and type of the elements being operated on, from .u8 (unsigned byte) to .f32 (single-precision floating-point): for instance, vqadd.s16. If the element size changes as part of the operation, the prefix indicates the element size of the narrowest input. Some instructions only need the element type to be partially specified, for instance vadd can operate on .i16, as it only needs to know that the elements are integers (and their sizes), not whether they are signed or unsigned; some instructions even only need the element size (e.g. .32). However, always use the most specific data type you can, for instance if you’re currently operating on u32 data, then specify .u32 even for instructions that would just as well accept .32: the assembler will accept it and it will make your code clearer and easier to type-check.

A little historical note: NEON instructions used to have a different syntax, and some of them changed names. Notably, instructions where the element size changed took two prefixes, with the size after and before (e.g. .u32.u16). This is something you may still see in disassembly, for instance. And, for some reason, the iPhone SDK assembler only accepts instruction mnemonics in lowercase, so while the instructions are uppercase in the documentation, be sure to write them in lowercase.
<h4>Instruction Overview</h4>
It is way out of the scope of this blog post to provide a full breakdown of the NEON capabilities (like, for instance, <a href="http://developer.apple.com/hardwaredrivers/ve/sse.html">http://developer.apple.com/hardwaredrivers/ve/sse.html</a> does for SSE). I will just give you a quick rundown of each major area to get you started, after that the documentation should be enough.
<h5>Load and Stores</h5>
NEON of course has a vector load and a vector store instructions, and even has vector load/store multiple instructions. However, these instructions are typically only used for saving/restoring registers on the stack and loading constants, both places where you can easily guarantee alignment, as these instructions demand word alignment. To load and store the data from the streams you will be operating on, you will typically use vld1/vst1; these instructions handle unaligned access, and the element size they take in fact pretty much acts as an alignment hint: they will expect the address to be aligned to a multiple to the element size.

Much more interesting are the vld#/vst# instructions. These instructions allow you to deinterlace data when loading, and reinterlace it when storing; for instance if you have an array of floating-point xyz structures, then with vld3.f32 you will have a few x data neatly loaded into one vector register, with another vector register containing the y and a third the z. Even for two-element (e.g. stereo audio) or four-element (e.g. 32-bit RGBA pixels) interlaced data, it avoids you the temptation to operate on non-uniform data, instead everything is neatly segregated in its own register (one register holds all left, one register holds all alpha, etc.). Notice these have the option to operate on non-consecutive registers of the form {&#60;Dd&#62;, &#60;Dd+2&#62;, &#60;Dd+4&#62;, &#60;Dd+6&#62;}, so that you can load/store Q registers using two of these instructions (one filling the low D halves, one the high D halves).

These instructions can also load one data or one structure to a particular element of a register, so scatter loading (not that it should be abused) is even easier than with SSE; you can also load the same data to all elements of the register directly.

In NEON you can’t really do software realignment, as just like SSE there is no real support for this (vext looks tempting, until you realize the amount is an immediate, fixed at compile time). By starting with a few scalar iterations, you may be able to align the output stream to a multiple of the vector size; however the other streams are typically not aligned to a vector boundary at this point, so use unaligned accesses for everything else.
<h5>Permutation</h5>
NEON does have a real permute with vtbl/vtbx, however it doesn’t come cheap. Loading a Q vector with permuted data from two Q vectors, which is the equivalent of an AltiVec vperm instruction, will require issuing two instructions which will take 6 cycles in total on a Cortex A8, so save this for when it’s really worth it.

For permutations known at compile time, you should be able to combine the various permutation instructions to do your bidding: vext, vzip/vuzp, vtrn and vrev; vswp can be considered a permutation instruction too, it can serve as the equivalent of vtrn.64 and .128 (which don’t exist) for instance. vzip in particular acts a bit like AltiVec merge, though the fact it overwrites its inputs makes it slightly unwieldy. Don’t forget you can use the structured load/store instructions to get the data in the right place right as you load it, instead of permuting it afterwards.
<h5>Comparisons and Boolean operators</h5>
There are a variety of comparison instructions, including ones which compare directly to 0; as is customary, if the comparison is true, the corresponding element is set to all ones, otherwise to all zeroes. There is the usual array of boolean operators to manipulate these masks, plus some less usual ones such as XOR, AND with one operand complemented, and OR with one operand complemented. Oh, and there is a select instruction (in fact, three, depending on which input you want to overwrite) to make good use of these masks.
<h5>Floating-Point</h5>
NEON floating-point capabilities are very similar to AltiVec. To wit:
<ul>
	<li>just like AltiVec, only single-precision floating-point numbers are available</li>
	<li>by default, denormals are flushed to 0 and results are rounded to nearest</li>
	<li>only estimates to reciprocal square root and reciprocal are given, refinement steps are necessary to get the IEEE correct result</li>
	<li>there are single-instruction multiply-add and multiply-substract</li>
</ul>
This is not to say there is no difference, however:
<ul>
	<li>contrary to AltiVec, multiply-add seems to be UNfused, there is apparently an intermediate rounding step</li>
	<li>probably related to the previous point, refinement step instructions for reciprocal square root and reciprocal are provided.</li>
	<li>denormal handling cannot be turned on</li>
	<li>conversion to integer necessarily rounds towards 0</li>
	<li>there are no log and 2<sup>x</sup> estimates</li>
	<li>some horizontal NEON operations are available, as well as absolute differences.</li>
</ul>
<h5>Integer</h5>
I’d qualify the integer portions of NEON as very nimble. For instance, you can right shift at the same time as you narrow, allowing you to extract any subpart of the wider element, and not only that, but you can round and saturate at the same time as you extract, including unsigned saturation from signed integer; very useful for extracting the result from an intermediate fixed-point format. The other way round, you can shift left and widen to get to that intermediate format. Simple left shifts can also saturate; without this, extracting bitfields with saturation is really unwieldy. There are also shift right and insert which allow to efficiently pack bit formats, for instance.

The multiplications are okay, I guess, though vq(r)dmulh is pretty much your only choice for a multiplication that does not widen and is useful for fixed-point computations, so better learn to love it.
<h5>Miscellaneous</h5>
Though not part of NEON, I should mention the pld (preload) instruction, which has been here since ARMv5TE, as such memory hint/prefetch instructions are often closely associated with SIMD engines. Architecturally, the effect of the pld instruction is not specified, the action performed depends on the processor. On the Cortex A8, this instruction causes the cache line containing the address to be loaded in the L2 cache; on the Cortex A8 the NEON unit directly loads from the L2 cache. If you do use pld, make sure to benchmark the performance before and after, as it can slow down things if used incorrectly.

In general, the documentation from ARM is of good quality, however there are not many figures to explain the operation of an instruction, so you should be ready to read accurate but verbose pseudocode if you’re unsure of the operation of an instruction or need to check it does what you think it does.
<h4>Cortex A8 implementation of NEON</h4>
<p id="">The Cortex A8 implements NEON and VFP as a coprocessor “located” downstream from the ARM core: that is, NEON and VFP instructions go through the ARM pipeline undisturbed, before being decoded again by the NEON unit and going through its pipeline. This has a few consequences, the main one being that, while moving a value from an ARM register to a NEON/VFP register is fast, moving a value from a NEON/VFP register to an ARM register is very slow, causing a 20 cycle pipeline stall.</p>
On the Cortex A8, most NEON instructions execute with a single cycle throughput; however, latencies are typically 2 or more, so directly using the result of the previous instruction will cause a stall; try to alternate operation on two parallel data to maximize throughput. Some NEON instructions that operate on Q vectors will execute in two cycles while they take only one when operating on D vectors, as if they were split in two instructions that operate on the two D halves (and in fact this is probably what happens); not much you can do about it, just something to know (not really unusual, remember that up until the Core 2 duo, Intel processors could only execute SSE instruction by breaking them in two since key internal data paths were only 64-bit wide, so all 128-bit instructions took two cycles). However, vzip and vuzp on Q vectors actually take 3 cycles instead of 1 for D vectors, since when operating on Q vectors the operation can not be reduced to two operations of D vectors.
<p id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown">The Cortex A8 has a second NEON pipeline for load/store and permute instructions, so these instructions can be issued in parallel with non-permute instructions (provided there is no dependency issue). Remember the Cortex A8 (and its NEON unit) is an in-order core, so it is not going to go fetch farther instructions in the instruction stream to extract parallelism: only instructions next to each other can be issued in parallel. Notice that duplicating a scalar is considered a permute instruction, so provided you do so a bit before the result is needed, the operation is pretty much free.</p>
One last consideration from <a id="" href="http://blogs.arm.com/software-enablement/coding-for-neon-part-2-dealing-with-leftovers/">a recent ARM blog post</a> is that you shouldn’t use “regular” ARM code to handle the first and last scalar iterations, as there is a penalty when writing to the same area of memory from both NEON and ARM code; even scalar iterations should be done with NEON code (which should be easy with single element loads and stores).
<h3>Oh, you mean I have to conclude?</h3>
My impression of NEON as a whole so far is that it seems a capable SIMD/multimedia architecture, and stands the comparison with AltiVec and SSE. It doesn’t have some things like sum of absolute differences, and there are probably some missing features I haven’t noticed yet, so it still has to grow a bit to reach parity, but it is already very useful.]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/08/introduction-to-neon-on-iphone-zz.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《变形金钢3》之黑月降临观后感</title>
		<link>http://www.vcfans.com/2011/07/transformers-dark-of-the-moon.html</link>
		<comments>http://www.vcfans.com/2011/07/transformers-dark-of-the-moon.html#comments</comments>
		<pubDate>Sat, 30 Jul 2011 15:29:38 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站杂谈]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[电影]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1508</guid>
		<description><![CDATA[<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/07/transformers3.jpg"><img class="alignnone size-full wp-image-1509" title="transformers3" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/07/transformers3.jpg" alt="" width="800" height="450" /></a>

下午，和老婆一起带着弟弟妹妹去左岸把《变形金钢3》给看了，电影院人山人海呀，团购的热潮为电影业带来了不少人气，到哪都要排队，话又说回来了中国有办事不排队的地方么？

这次观影感受如下：

１.《变形金钢3》的打斗场面很多，基本是从头到尾，场面还行，情节性的内容很少，总是打来打去的，很没意思。难到我真的老了与大众口味相差这么大？变三还没有变二具有可看性。打斗场面固然很重要，但好的情节才是王道。下次不想再去看电影院去看这类片子了，还是在家看看高清就够了。

２.广告N多，什么牛奶呀、电脑呀、什么网络设备呀以及什么打印机呀等，其中的电脑广告特写了好几次，这将来是个趋势，只要导演能处理好，我不反对。另个，尼妈的电影院搞的还是国内代理商搞的，在电影开头插了N多广告，艹，看了半天，提示“请配戴3D眼晴观看以下内容”，原来尼妈是用3D拍的广告。广告排的巨烂无比，毫无创意。我认为在片头插广告的行为绝对的流氓，尼妈，老子是花钱买的电影票去看电影的，不是去看你广告的。中国奸商做事怎么就这么流氓呢？还这么多奸商，艹。

3.普通3D影片，票价已经涨到70一张了，扛不住呀，以后坚决打住少去电影院。

4.总共才160分钟，我小弟居然睡了一个多小时。哥的电影票可是全价票，他说看的头晕，现在的娃真伤不起。

&#160;]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/07/transformers-dark-of-the-moon.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend的解密程序绿色版</title>
		<link>http://www.vcfans.com/2011/07/zend-green-version-of-the-decryption-program.html</link>
		<comments>http://www.vcfans.com/2011/07/zend-green-version-of-the-decryption-program.html#comments</comments>
		<pubDate>Sat, 30 Jul 2011 14:58:04 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[常用工具]]></category>
		<category><![CDATA[软件]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1504</guid>
		<description><![CDATA[一兄弟在网上找了一份免费的小型网站后台程序，PHP的，我帮其架好后，总是无法use database，数据库访问类居然还用zend加密了，你加密是可以的，但这样影响我帮你修bug呀。

在网上找了一份zend解密的程序，测试可用。解密修正代码，收工。

绿色版，支持php-4.2.0、php-4.2.x、php-4.3.x、php-4.4.x、php-5.0.x、php-5.1.x、php-5.2.x，下载后放到Ｄ盘根目录下。

如果要修改位置请修改Dezender\PHP5\PHP5\php.ini最后两行的路径。

[download id="114"]]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/07/zend-green-version-of-the-decryption-program.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>黄山归来</title>
		<link>http://www.vcfans.com/2011/06/huangshan-return.html</link>
		<comments>http://www.vcfans.com/2011/06/huangshan-return.html#comments</comments>
		<pubDate>Sun, 26 Jun 2011 15:54:14 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站杂谈]]></category>
		<category><![CDATA[公司]]></category>
		<category><![CDATA[旅游]]></category>
		<category><![CDATA[生活]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1493</guid>
		<description><![CDATA[某公司前段时间组织一次旅游，我们组选择了黄山二日。深深同情一下选择牯牛降线路的同学，每到周末连连暴雨，至今未能出行呢。身为安徽人至今未去过黄山，有点小杯具。只是与黄山神交已久，一直未能如愿。此次终于把握住机会了，一定要去爽一吧。本来想让老婆和我一起的，可惜后来由于种种原因，还是我一人单枪匹马赴会了，哈~。

一大早出门，阳光普照心里好爽呀，这么好的天气正好去游山玩水。经过三个多小时的车程，到达黄山景区时，下起来瓢泼大雨，我勒个去，和合肥的天气差别怎么就这么大呢？不过吉人自有天相，第一天的行程是游翡翠谷，不爬山。翡翠谷又名情人谷，据说是当年周润发在那拍过《卧虎藏龙》，感觉那场地也不大，看样子后期处理还是比较重要的。

由于前一天下了一天的雨，第二天一早居然放晴了，老天爷真是给力呀，由于刚下过雨，我们还见到了云海，不虚此行呀。

一直都想登一回黄山，这次机会不能放过，我和几位同事选择徒步，直达山顶。

这是我们这一组登山的同学，到达“北海”与索道组的同学么汇合的地方。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan2.jpg"><img class="alignnone size-full wp-image-1496" title="huangshan2" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan2.jpg" alt="" width="800" height="531" /></a>

由于第二天还要上班，我选择了坐索道下山，保存体力哈。其中一哥们，居然也是徒步走下山鸟，搞马拉松就是不一样，佩服一下先。

这是我们山爬到一半之处拍的到，由于相机比较差，实际效果比照片要好很多。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/P5140141.jpg"><img class="alignnone size-full wp-image-1497" title="P5140141" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/P5140141.jpg" alt="" width="800" height="600" /></a>

看看我们那天行走的路线吧，还是很牛比的。

云谷寺-&#62;入胜亭-&#62;仙人指路-&#62;白鹅岭-&#62;白鹅山庄-&#62;北海-&#62;光明顶-&#62;莲花峰，然后看到了传中的安徽一宝迎客松了，坐索道下山。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/P5150166.jpg"><img class="alignnone size-full wp-image-1498" title="P5150166" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/P5150166.jpg" alt="" width="800" height="600" /></a>

这就是传说中的迎客松了，现在是淡季排了半天队才得到一个拍照的机会，不容易呀。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan.jpg"><img class="alignnone size-full wp-image-1499" title="huangshan" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan.jpg" alt="" width="800" height="531" /></a>

最后我们来张合照，准备下山鸟。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan4.jpg"><img class="alignnone size-full wp-image-1500" title="huangshan4" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/huangshan4.jpg" alt="" width="800" height="531" /></a>

此次为第一次登黄山，看的不是很仔细，下次有机会一定要再登黄山，好好品一品。也不知道是多少年后的事鸟。

如果有朋友想去的，建议直接登山，其他的周边景色都浮云，别处也可以看到。不过西递宏村，据说不错没时间参观，下次吧。]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/06/huangshan-return.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>六一节礼物</title>
		<link>http://www.vcfans.com/2011/06/sixty-one-gift.html</link>
		<comments>http://www.vcfans.com/2011/06/sixty-one-gift.html#comments</comments>
		<pubDate>Wed, 01 Jun 2011 17:19:38 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站杂谈]]></category>
		<category><![CDATA[节日]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1488</guid>
		<description><![CDATA[某公司很给力，居然不忘了给我们这些大龄儿童，发点节日礼物。相当的怀念小时候，每年的今天，老师发糖放假的美好时光。

下午收到这份小礼物，感觉很不错，哈哈。

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/1306912319895.jpg"><img class="alignnone size-full wp-image-1489" title="1306912319895" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/1306912319895.jpg" alt="" width="300" height="500" /></a>

<a href="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/1306912455743.jpg"><img class="alignnone size-full wp-image-1490" title="1306912455743" src="http://www.vcfans.com/wp-content/vcfans-upfiles/2011/06/1306912455743.jpg" alt="" width="300" height="500" /></a>

热血青年呀~~~~]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/06/sixty-one-gift.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>RVDS 2.2 Introductory Tutorial</title>
		<link>http://www.vcfans.com/2011/06/rvds-2-2-introductory-tutorial.html</link>
		<comments>http://www.vcfans.com/2011/06/rvds-2-2-introductory-tutorial.html#comments</comments>
		<pubDate>Wed, 01 Jun 2011 16:59:27 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[文档资料]]></category>
		<category><![CDATA[编程开发]]></category>
		<category><![CDATA[嵌入式]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1483</guid>
		<description><![CDATA[来官方的arm平台自带工具的介绍，非常浅显易懂，值得看看。
[download id="113"]]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/06/rvds-2-2-introductory-tutorial.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《从一道小学数学试题的解法到家长的焦虑》</title>
		<link>http://www.vcfans.com/2011/05/from-a-primary-school-mathematics-questions-of-the-solution-to-the-anxiety-of-the-parents.html</link>
		<comments>http://www.vcfans.com/2011/05/from-a-primary-school-mathematics-questions-of-the-solution-to-the-anxiety-of-the-parents.html#comments</comments>
		<pubDate>Fri, 27 May 2011 16:34:25 +0000</pubDate>
		<dc:creator>lonkil</dc:creator>
				<category><![CDATA[本站杂谈]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[幽默]]></category>

		<guid isPermaLink="false">http://www.vcfans.com/?p=1476</guid>
		<description><![CDATA[请参见原地址：<a href="http://www.tianya.cn/publicforum/content/free/1/2153124.shtml">《从一道小学数学试题的解法到家长的焦虑》</a>

其中涉及到的两种算法是：

儿子四年级了，前几天参加期中考试，有一道数学简便计算题是575÷25，儿子的解法是：
<div class="comment">
（600-25）÷25
=600÷25-25÷25
=24-1
=23</div>
对儿子的解法，老师打了一个大大的红叉。老师的解法是：
<div class="comment">
（500+75）÷25
=500÷25+75÷25
=20+3
=23
</div>

这位父亲比较郁闷，感觉老师误人子弟了。其实从计算机的角度来分析，这位老师还是很英明滴，^_^.让我们一起看看：
<pre lang="Python" line="1"  colla="+"> 
import time

if __name__ == "__main__":
    
    tm = time.clock()
    for i in range(0,9000000):
      result = 600 / 25 - 25 / 25
    tm = time.clock() - tm
    print("The result of son is %d, Cost time %fs" % (result,tm) )

    tm = time.clock()
    for i in range(0,9000000):
      result = 500 / 25 + 75 / 25
    tm = time.clock() - tm
    print("The result of teacher is %d, Cost time %fs" % (result,tm) )
</pre>

在我这台2800+上的跑的结果如下：
<div class="comment">
D:\>speed.py
The result of son is 23, Cost time 5.226447s
The result of teacher is 23, Cost time 5.072127s

D:\>speed.py
The result of son is 23, Cost time 5.135097s
The result of teacher is 23, Cost time 5.072602s
</div>

虽然两者的结果都是一样，但是我们人民老师的算法耗时，严重优于这位同学。老师不亏是老师佩服一下，作为一名小学数学老师连减法运算比加法运算耗时，这么底层的知识都明白，并贯彻到日常教学中去，实在是牛呀。

PS:我这台老机器速度，让我压力太大了。]]></description>
		<wfw:commentRss>http://www.vcfans.com/2011/05/from-a-primary-school-mathematics-questions-of-the-solution-to-the-anxiety-of-the-parents.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.613 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-05 10:08:44 -->

