The arm structure that IOS developers should know

Source: Internet
Author: User
Tags integer division

The original source cannot be found.

When I wrote "getting started with the neon iPhone", I thought that the reader had a better understanding of the processor knowledge of iOS devices. However, after reading some discussions on the internet, I found that the original knowledge is not popular, and it is my fault. In addition, I think understanding these things is helpful for iPhone programming (not just for those who like neon)
Even if you are using objective-C, even if you do not understand it, it will not affect your work, but this knowledge will make you a better iPhone programmer.

Basic

So far, all IOS devices use arm
Structure processor, which is somewhat different from x86 and PowerPC on the desktop, but it is definitely not a "special" or "niche" product. Almost all mobile phones (not just smartphones) are based on ARM, such as almost all iPod, almost all MP3 players, PDAs, and Pocket PCs, not to mention. Nintendo has been transferred from GBA to arm, and it has even penetrated into the graphics calculator's territory and appeared in some deyi and HP calculators. If you want to continue tracing the source, Newton uses arm (Apple was an early investor in arm ). In addition, there are only a few gadgets mentioned above, and countless arm processors are running in embedded systems.

Arm is famous for its low power consumption and small size, and its performance is also outstanding in products with the same power consumption. This structure (at least on the iOS platform) uses little-Endian sorting, just like x86. Like MIPS and PowerPC, it belongs to a 32-bit RISC structure. Note that the simulator does not run arm code, and the software is compiled into instructions that can be run on x86. Therefore, the following content applies to the target device, not the simulator.

Armv7, arm11, Cortex A8, and A4, dear!

Over the years, the arm structure has evolved into several different versions. Each version has added new commands and maintained backward compatibility. The first-generation iPhone uses the armv6 processor (abbreviated as arm 6), while the latest iPhone 4 supports armv7. Therefore, different commands are generated according to the instruction set of the target version during code compilation. The same is true for assembler programs. The commands used in the Code must be compatible with specific versions. Finally, generate the machine code corresponding to armv6 or armv7 (or armv5 and V4, but armv6 is the bottom line of iOS development, so you don't need to consider the two ). The target file and the executable file have their own versions. You can run
Otool-Foo. O.

However, it is wrong to say that "the first-generation iPhone 4 was equipped with the armv6 processor" because armv6 is not a specific processor, but an instruction set that can be run by the processor. The first generation of iPhone uses the arm 11 core (ARM1176JZF-S, but it doesn't matter, as long as you remember it is a member of the arm 11 family), as I mentioned earlier, this processor uses the armv6 instruction set. Later iOS devices still use arm11, until the release of the iPhone 3gs, Apple began to switch as much as possible to the core of the cortex A8 processor (although not sure yet, the iPhone 4 is likely to use
A8 ). This core uses the armv7 instruction set. In this case, it supports armv7.

As I have already said, Do not implant device judgment code in a program, and then detect the arm structure supported by the device through known information. This code is extremely unreliable and runs on a new device that is released only after the software is complete, resulting in interruptions. So please do not do this, otherwise I swear, I will go to your house to waste you. The above knowledge is used to give you a rough understanding. Some devices support armv7 and some devices support armv6. As for how to detect it, I will talk about it now.

However, you may think, "the iPad and iPhone 4 Use A4, not cortex A8, right ?」 Otherwise, A4 is actually a complete single-chip system (SOC), not only the cortex A8 kernel, but also the graphic hardware, audio and video coding accelerator and other digital modules. A single-chip system and a processor are two very different concepts. The processor does not even occupy the main space on the silicon chip.

If you do not know how to use it, even if the device supports armv7, it will not help. Of course, there is no problem with applying the new instruction set, but if you do this all the time, the early devices won't be able to run the code you wrote. I guess this may not be the result you want. So how should we detect the structures supported by the device? -You can make good use of armv7 only by determining whether it supports armv7. The answer is: no need to know. Instead, compile the code twice, one for armv6, and the other for armv7, and then package these two executable files into a cool binary file. Okay. When running, the device determines which one is better to open. Yes, Mach-O can be used not only to combine completely different CPU Structures (for example
PowerPC and Intel), or 32-bit and 64-bit versions with the same structure, it can also deal with two variants of the same structure, in the Mach-O term, this is called the CPU subclass. From the programmer's point of view, the result is: Compilation determines everything. Code Compiled for armv6 only runs on armv6 devices. Similarly, the Code Compiled for armv7 only runs on armv7 (or better) devices.

If you have read the neon Post I wrote, you may remember that I have recommended a method for detecting and selecting structures at runtime. If you try again, you will find that I have removed the part. Now, I do not recommend that you do this, because although this is indeed useful, it cannot be ensured (or, the skills required are too complex to ensure that errors are not met.) It will be able to run stably on future armv8 processors. The status of related APIs in this document is not important (not on the IOS manual page). If you want to run on armv6 and want to use arm7v, use the method you just mentioned.

Note: In iOS, the arm structure may not reflect the processor model. For example, the IOS code corresponding to armv6 requires the support of floating point commands (vfpv2, to be precise). For armv6, although this is optional, however, it has existed since the first generation of the iPhone was released. Therefore, if armv6 is mentioned in iOS development (such as the compiler-arch setting or a CPU subclass of an executable file), it means hardware floating point support is required. This is also true for armv7 and neon: Although neon is actually an option for ARMv7-A configuration, it appears in all
IOS devices. Therefore, when it comes to iOS neon, it refers to armv7.

Conditional execution

A practical function of the arm structure is that most commands can be executed conditionally-if the conditions are not met, the commands are invalid. This can shorten the process and make the block deployment more effective. The general method is to skip this step if the block does not meet the conditions, but this step is skipped by inserting the judgment command into the block.

If this is just a way for the compiler to improve code efficiency, I will not mention it here. Although this is indeed a function of debugging, it is mentioned because it may be surprising when debugging (debugging. In fact, sometimes you will find that the debugger will enter a false condition block (ifblock, for example, early error return) or two branches of IF-Else. This is because, although the Code passes through the processor as much as possible, some of the Code is not actually executed, that is, conditional execution. In addition, if you place a breakpoint in such a condition block, even if the status is false, it may still be executed.

Even so, in my limited test, the compiler seems to refuse to generate conditional execution commands in the debugging configuration. Therefore, it should only happen after debugging and optimization code. Unfortunately, sometimes you have no choice but to do so.

Thumb

The thumb instruction set is a subset of the arm instruction set. After compression, the command is only 16 bits (the size of all arm commands is 32 bits, and it is still a 32-bit structure, this is not a completely different structure, but should be regarded as the abbreviation of common arm commands and functions. Its advantage is obviously to greatly reduce the code size, save memory, cache, and code bandwidth. Although it is more suitable for memory-intensive microcontroller-type applications, it is still useful on iOS devices, and because of this, xcode enables this feature in IOS projects by default. Although the code size is greatly reduced, it is impossible to reach 50%, because sometimes one
The arm Command requires two corresponding thumb commands. The arm and thumb commands cannot be mixed at will. The processor needs to switch the two to different modes, which can only occur when a function is called or returned.

When the target platform is armv6, the compilation of the thumb command is facing a lot of trade-offs. The thumb code of armv6 has fewer registers and lacks conditional commands. In particular, it cannot use floating point hardware, such as floating point addition, subtraction, multiplication, and so on. To use the floating point thumb code, you must call the system function. That's right. It sounds like a very slow process. For this reason, we recommend disabling the thumb mode for armv6, but if you insist on this, make sure to analyze the code first. If some parts are slow, at least disable thumb (it is easy to use the command line parameter-MnO-thumb in xcode ). Remember that floating point operations are performed on
It is common in IOS because quartz and core animation use floating point coordinate systems.

When the target is changed to armv7, all these shortcomings disappear: armv7 contains thumb-2, which is an extension set of the thumb command, added conditional execution and 32-bit thumb commands that can access all arm registers and hardware floating point and neon. Using thumb-2 to reduce the code cost is almost zero, so it is best to turn it on (if it is turned off, please open it again ). In the condition generation option of xcode, enable armv7 and disable armv6.

You may hear people say on the Internet that the Code needs interworking to use thumb. Don't worry unless you want to write assembly code, because all the code on the iOS platform is interconnected. When the Assembly is displayed, it may be difficult for the shark to determine whether the function is arm or thumb. If you see invalid or meaningless commands, you 'd better check each other.

Alignment

IOS supports non-alignment access, but it is slower than alignment access. We recommend that you do not use it. In some special cases (involving loading/storing multiple commands, if you are interested), non-alignment access may be a hundred times slower than alignment access because the processor cannot process it, you must also request assistance from the operating system (refer to this article, which corresponds
It is the same phenomenon that non-alignment Double Precision Floating Point Numbers become too slow on powerpc ). So be careful, and alignment is still important.

Division

This guy always surprised everyone. Open the arm structure Manual (if you do not have one, refer to the structure overview section of "Neon iPhone getting started") and find the integer division command. Let's go. I will wait for you. Not found? Normal and normal. Yes, the arm structure does not support hardware integer division and must be executed by software. If you compile the following code:

int ThousandDividedBy(int divisor)
{
return 1000/divisor;
}

In the assembly code, you will see that the compiler inserts a "___ divsi3" that calls the function-this is a system function used to execute the software division (note that the divisor cannot be constant, otherwise, Division may be converted to multiplication ). This means that
In arm, integer division actually represents the performance of the operating system.

However, after reading the manual, you may say, "You are wrong! There are even two arm division commands in it! Here, sdiv and udiv !」 Sorry for the cool water, these commands can only be used for ARMv7-R and ARMv7-M configuration (both for real-time and embedded environments-such as motor microcontroller and watches ), IOS device ARMv7-A is not supported, sorry!

Gcc

The quality of arm code generated by GCC is no longer a secret. On other ARM-based platforms, professional developers use the rvds tool chain provided by arm itself. However, rvds
The Mach-O runtime for OSX is not supported, but only elf Runtime is supported, so there is no difference on the iOS platform. But at least there are alternatives to GCC, such as llvm. Although I did not test it, but when using llvm, at least we saw significant improvements in 64-bit full-Digital (this, GCC)
Especially weak on arm ). In time, llvm surpassed GCC in all aspects.

You see, now you are a better IOS developer!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.