asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:1698回复:0

在amd看到的

楼主#
更多 发布于:2005-07-07 17:03
  Tricks for Porting Applications to 64-Bit Windows on AMD64 Architecture
The underlying theme with Windows and AMD64 is "compatibility." The AMD Athlon 64 and Opteron processors have native hardware support for 32-bit x86 code and AMD64 extensions. Sixty-four bit Windows runs 32-bit and 64-bit apps side-by side, seamlessly. And a single C/C++ source tree compiles to both 32-bit and 64-bit binaries, so your apps can run on both AMD64 and legacy x86 platforms. AMD's Mike Wall explains how to make the port.

by Mike Wall, AMD November 11, 2003
 
 
The AMD64 architecture gives you the best of both the 64-bit and 32-bit worlds. That's because, depending on the operating system that you load, an AMD64 processor can run both the "classic" 32-bit versions of Windows, such as Windows 2000, Windows XP, or Windows Server 2003, or it can run the special 64-bit extended versions of Windows XP and Windows Server 2003 that Microsoft is currently beta-testing.

The real flexibility comes when the processor loads the 64-bit version of Windows; in that mode, called Long Mode, the computer can run both 32-bit and 64-bit Windows applications at full hardware speed. The backward compatibility with 32-bit applications is provided by the AMD64 processor on the hardware side; the operating system handles 32-bit calls by using a special technology called WoW64, for Windows-on-Windows 64, that translates 32-bit pointers and arguments into 64 bits and back again.

(A 32-bit application can find out whether it's running under WoW64 by calling the IsWow64Process function. Learn more about that function here.)

From a business and usability perspective, that means that users can keep all their existing 32-bit Windows apps, while being able to take advantage of the higher performance of any native 64-bit apps that they may own―and that's definitely the best way for users (and businesses) to begin the migration to the 64-bit world. And it eliminates much of the business risk for developers, like you, to begin the migration as well, because you don't have to convince your customers to walk away from their software investments.

Why Port to 64-Bit Windows?
There are several good reasons to port to 64-bit Windows. Several billion good reasons, in fact, including large memory!

The memory limitation for an application on a 32-bit legacy Windows platform is two gigabytes, which must be shared by all the 32-bit processes that are running. The limit can be raised to 3GB for some applications, but that's the absolute maximum address space. On 64-bit Windows, that limitation is blown out of the water―you're talking about a huge virtual address space, and hardware support for terabytes of physical memory.

That's not all. When running with a 64-bit operating system, 64-bit applications have access to 64-bit pointers, and many new 64-bit general-purpose registers and 128-bit floating-point registers. That gives your application much greater efficiency in performing complex operations within the processor, using registers to store all the variables.

The upshot: Fast performance, even when you're not taking advantage of that larger address space. Math-intensive operations, such as codecs, simulation, 3D, gaming, compression, and cryptography really fly using those extra registers and instructions. In most cases, unless you're an assembly programmer you won't have to worry about the details, because your AMD64 architecture optimizing compiler will help your app take advantage of those extra on-chip resources.

"Some Code Really Must Be Ported"
Plus, in most cases, you can use a single source tree for both 32-bit and 64-bit versions of your applications. Use different makefiles, with the correct libraries (see "Some Code Really Must Be Ported") and compiler switches to compile binaries for both 32-bit and 64-bit platforms.

Integer Data, Pointers, and Arithmetic
There's some excellent advice about the porting process on the DevX AMD DevSource, such as Joe Devine's "How to Automate your 64-Bit Migration," so there's no reason to duplicate that advice. However, there are some pointers that I'd like to share regarding porting C/C++ code to 64 bits.

First, bear in mind that programming for 64-bit Windows is basically the same as programming for 32-bit Windows. You'll use the same APIs and programming conventions. However, you will encounter a few new data types. For example, int and long remain 32 bits, but pointers become 64 bits. That means that you'll have to be careful about finding, and fixing, any implicit assignments between ints and pointers in the code. To put it another way: do not cast pointers to int, long, ULONG or DWORD.

What should you use? If you're using Microsoft's Visual C++, you now have polymorphic data types for pointer math:

HALF_PTR: Half the size of a pointer. Use within a structure that contains a pointer and two small fields.
INT_PTR: Signed integral type for pointer precision.
LONG_PTR: Signed long type for pointer precision.

UHALF_PTR: Unsigned HALF_PTR.
UINT_PTR: Unsigned INT_PTR.
ULONG_PTR: Unsigned LONG_PTR.

SIZE_T: Use this type for a count that must span the full range of a pointer.
SSIZE_T: Signed SIZE_T.

These types, which are defined in basetsd.h, automatically scale to match the 32-bit or 64-bit mode at compile time.

For example, the following is bad code:


char *p;
long Lval
Lval = p; //bad! Truncated in 64-bit mode

Better code would be:


char *p;
LONG_PTR Lval; //either 32 bits or 64 bits
Lval = p; //works fine

Another bad bit of code casts a pointer to a long. Such code would run fine on 32-bit Windows, but the pointer will get truncated when you compile the code for 64-bit Windows.


objectStart = (PVOID) ((ULONG) objectStart | 1);

So, instead, you should write the code using one of the polymorphic data types:


objectStart = (PVOID) ((ULONG_PTR) objectStart | 1);

Data Alignment
On all operating systems and platforms, data alignment can affect performance. While the AMD64 architecture places few restrictions, you should be aware that there are structural requirements in the ABI (application binary interface) regarding alignment. Plus, structure padding can affect code portability between 32-bit and 64-bit Windows.

A data access is aligned if its address is a multiple of its operand size, in bytes. Byte accesses are always aligned. Word (two-byte) accesses are aligned if their address is a multiple of 2. Doubleword (four-byte) accesses are aligned if their address is a multiple of 4, and of course, quadword (eight-byte) accesses are aligned if their address is a multiple of 8.

According to the AMD64 Architecture Programmer's Manual, Vol. 1, "The AMD64 architecture does not impose data-alignment requirements for accessing data in memory. However, depending on the location of the misaligned operand with respect to the width of the data bus and other aspects of the hardware implementation (such as store-to-load forwarding mechanisms), a misaligned memory access can require more bus cycles than an aligned access. For maximum performance, avoid misaligned memory accesses."

For more about data alignment, order or download the AMD64 Architecture Programmer's Manuals.

Working with Assembly Code
Assembly code is straightforward to port to AMD64 and 64-bit Windows―and is worth the effort for performance reasons! For example, you can take advantage of the new 64-bit general-purpose registers (r8-r15), and new floating point and 128-bit SSE/SSE2/floating point registers (xmm8-xmm15). However, there are new 64-bit stack frames and calling conventions you should learn about in the ABI (application binary interface) specifications.

The AMD64 Software Conventions document (also known as the AMD64 ABI Specification) is in the Microsoft DDK for AMD64. You should download and install the DDK and the Platform SDK for AMD64 to have access to those ABIs and the documentation.

Note that in-line assembly code is not supported with the Microsoft C/C++ compiler and libraries. So, you have to put the assembly code into a separate MASM file. By the way, compiler intrinsic functions are an alternative to assembly code, and are provided to implement most SSE and SSE2 instructions, in a manner that compiles seamlessly for both 32-bit and 64-bit targets. To learn more, search MSDN for "AMD64 Compiler Intrinsic Functions."

Streaming SIMD Extensions
The AMD Athlon 64 and Opteron processors fully support 32-bit 3DNow!, x87 and MMX instructions for 32-bit applications, whether they're running on 32-bit or 64-bit Windows. However, those instruction sets are not supported for native 64-bit applications. Instead, you should use SSE and SSE2 instructions. Those instructions provide you with terrific performance for single-precision and double-precision floating point and integer SSE2 vector operations―and it's not difficult to do the port.

For example, when you're converting MMX code to integer SSE2 code, the instructions are the same, but the registers are 128 bits wide instead of 64 bits. So, you will have to take care to align your data and use the MOVDQA instruction to handle the quadwords correctly.

Go Ahead and Port
More Exciting Porting and Portability Tips
When it's time to compile, use the /Wp64 switch with the Microsoft Visual C/C++ compiler; it's available on the 32-bit compiler, and using it is one of the first steps to porting. With that switch thrown, the compiler will warn you about portability issues―pay attention to those messages, since you want to get your code "64-bit clean." (If you're working with the "Whidbey" version of Visual Studio .NET, please note that it includes native support for compiling to AMD64 Windows platforms!)

Post compilation, be sure to test, test, test. You may find additional bugs in your code, especially when implicit conversions don't go as you'd expect. Be careful to keep synchronization between C and assembly data structures, and pay attention to the new data types, data sizes and alignments.

Finally, use benchmarking to help identify parts of your code that need extra attention after the port. The ideal tool is AMD CodeAnalyst , which you can download free of charge. DevX has written an article about it―see "Getting In Touch With Your Inner Code."
Page 1 of 1
游客

返回顶部