The early stages of porting software from the 32-bit environment to 64-bits can dramatically increase the efficiency and chances of success for the entire project. The guidelines covered here identify key considerations for migrating to the Intel Itanium Processor Family and Intel® 64 architecture.
By Armando Alcantar and Sreekanth Reddy Keesara
Porting software to 64-bit Intel® architecture requires that a software developer consider the overall scope, timelines, lines of code, functionality of the application, dependencies, process, and supporting tools that he/she may need to successfully complete the port. The purpose of this paper is to facilitate understanding the scope of porting, dependencies, build process, and tools required so that you, as the software developer, are aware of the issues that might sidetrack the porting effort.
A key value-adding aspect of the porting process is that migration to the 64-bit environment generally allows applications to run both on systems based on the Itanium® Processor Family and also on systems that support Intel® 64 architecture. The IA-32e operating mode on these processors allows a 64-bit operating system to run 64-bit applications, often requiring only a simple recompile of the 64-bit-clean code to run under Intel® 64.
Some primary caveats and limitations to this interoperability concern assembly, intrinsics, and macros; details are available from the Intel® 64 and IA-32 Architectures Software Developer's Manuals . Moreover, the same 64-bit operating system can also run most legacy 32-bit applications without modification under Intel® 64's IA-32e mode.
Mainstream languages that are typically ported are C++ and C. This article focuses on Windows* but is also relevant to various flavors of UNIX*
The following discussion provides an overview of the phases involved in the porting process, illuminating the possible pitfalls.
Understand the Scope of the Porting Effort
At the onset of any porting effort to the Intel Itanium Processor Family and/or Intel® 64, developers must consider whether the porting projection is based on Lines of Source Code (LOSC), or whether it is based on the functionality of the application.
Tran slating baseline functionality
These two possibilities require different scopes of effort, time requirements, interaction with the customer, manpower requisites, and deliverable schedules. Software developers should take the following considerations into account when scoping migration efforts: Conversion of 32-bit data types to 64-bit data types. For example, Windows* uses 64-bit pointers with 32-bit longs, while Linux* and HP-UX* use 64-bit pointers and 64-bit longs. Inclusion of specific Microsoft header files. In many flavors of UNIX, however, developers can write batch/shell scripts to set the build environment. If the developer uses an Intel® Compiler, 'eclvars.bat' or 'eclvars.sh' are useful.
Modification of compiler options
Identification of environment variables
Mapping of path-ways
Subsequent linking of supporting libraries and DLLs
Porting efforts based on total lines of code require a short learning curve, are relatively simple, have a short-term deliverable schedule, and may not use a full complement of development tools. Porting based on the functionality of the application requires proprietary application knowledge, application functionality, access to customer developmental tools, and alignment of deliverables schedules. These factors can have a substantial effort on the complexity of the porting effort.
Understanding the difference between porting based on LOC or porting based on functionality, at the onset, serves as an indicator for the optimal porting implementation.
Understand the Scope of the Dependencies
Dependencies can range in number, type, and depth of functionality. Types, such as code blocks for legacy versions of the application, hooks for legacy versions of operating systems, supporting libraries, Unicode interfaces, proprietary applications values (hexadecimal values for settings and thresholds), registry values and keys, proprietary header files, pointer tables, platform functions checks, and possibly creation of new modules, all must be identified beforehand. The functionality of commercially available application software, particularly, must not be compromised.
It is important to understand whether or not these dependencies share the same process space. The Intel Itanium processor is able to run x86 code in 32-bit mode or run PA-RISC code in an instruction-conversion mode. In a typical software-development environment, lines of code are generated at a rate of 8-15 lines per day. At first glance, this statistic is misleading. Embedded in this task is the mapping of req uirements to the code, creating the Pseudo Design Language (PDL) code, researching and establishing the interfaces and stubs for the code, and inserting comments in the code.
While a porting effort does not encompass all of these areas, a subset of them may be expected to impact the timeline. Given that the porting effort may include software development, one must be prepared to estimate a deliverable schedule. Man-hours of effort are calculated from these projections. A standard man-month consists of 19 days (four work weeks minus one day, accounting for average time off).
Porting will not require the same amount of time as writing the code. Typically, following warnings from the compiler or using a tool such as 'lint' can enable a developer to go through hundreds of lines of source code in a day.
The Build Process
Once the pseudo-build is delivered for final linking, command-line and Visual Studio* environment incompatibilities must be identified. Compiler options, Microsoft Foundation Classes (MFC) options, workspaces, environment variables, pathways, compile sequences, essential linked libraries and makefiles must be current. Any restriction on the use of a particular compiler must be identified. Using the Intel® C++ or Fortran Compilers may help to increase performance and increase the project's ultimate success. Link-time constraints that emerge must be resolved or deferred.
In any porting project, understanding the developmental challenges can be of great benefit. Porting might be from one platform to another or from one version of hardware to another; the process can be difficult unless the team completely understands the challenges that it might face. For example, in porting to a 64-bit Windows* environment, the following challenges exist: In the build process, many of the issues associated with these issues can be mitigated, but they should nonetheless be considered. One may have a customized or automated build process that cannot be readily exported off-site. This circumstance may arise when the porting effort is carried out at different development sites. An emulation for the build process, whether a sequence build of dependencies, temporary stubs, or selected modules, must be agreed upon beforehand.
Conventionally, builds are composed on Software Development Kits (SDKs) and Driver Development Kits (DDKs) that may not be the latest versions. Restrictions or constraints on the use of the latest versions should be identified. The composition of the build will, at times, have duplicate or similar pathways for different versions of DLLs found in the OS, SDKs and DDKs. Identifying the correct versions will expedite not only the configuration but also the build sequence. Naturally, all patches and updates must be applied.
Identify Deliverables and Set Preliminary Schedules
One may have to depend on third-party deliverables, over which one does not have control. When drafting a timeline or schedule, engineering judgment should be exer cised to allow for possible slips on the deliverable dates. Ideally, one will have performed due diligence and recognized the impact of these third-party deliverables, but it bears repeating that they should be identified in preliminary discussions. Many current software applications have dependencies on other software, drivers or firmware to work seamlessly in a software stack. These third-party dependencies must be identified prior to the start of the port. In order for the end-user to have a complete solution, all third-party dependencies must be identified as part of the port. After arriving at a conclusive list of dependencies, it is good practice to split them into three groups:
The first group consists of non-native applications, drivers and agents that are performance-critical and hence need to be ported natively.
The second group consists of non-native applications, drivers, and agents that are not performance-critical, and thus may not need to be ported, but for which thorough testing must be done to ensure complete functional validity.
Third-party code sharing the same process space should be ported. Workarounds with wrappers should be avoided.
Projection of deliverable schedules requires the collation of details from all of the above-stated parameters. Assess the number of developers available for the task, identify the focus of the port (i.e., lines-of-code or functionality), calculate the number of man-hours for each sub-task, calculate a sum total for the effort and make allowances for solution and/or dependency influences.
Establish End-User Interfaces
Consider end-user inputs in the planning designing and actual porting of the application, so that pre-defined expectations and requirements are met. A dynamic environment is essential for code development and porting. Inputs, by way of surveys from the clients, end-users and customers, are beneficial in developing a robust application.
The software development life-cycle requires that validation and verification of the application be conducted. This step must be undertaken in order to confirm proper functionality of the application on the ported platform.
Identify Requisite Tools
Porting is composed of various phases: clean compile, dependency identification, functionality validation and performance optimization. Specific tools are integral to each phase of the porting effort. Selecting the right tool for each phase of porting expedites the process. Compilers are used for the code-clean process. Intel compilers have many platform-specific switches that can greatly benefit application performance. They have robust support for Intel® Architecture, along with improved Linux* source compatibility and interoperability with gcc ABI 3.2 and 'C' binary mix/match with gcc. Microsoft .NET* Compilers may also used for this p hase, but they do not have some switches for processor-specific optimizations. 'Lint' is a valuable tool for use in UNIX ports.
There are some other tools that can be used in the "clean compile" phase, but which require the developer to have in-depth knowledge of the application code and compiler options. For instance, developers may benefit from Linux* emulators like the Cygwin Linux* emulator* and rules-based development tools like those from Parasoft*.
The Intel® VTune™ Performance Analyzer can be used in the performance-optimization phase for identifying the hotspots in the code, charting code flow path that can be used for performance analysis, and making code optimizations. Intel® Integrated Performance Primitives (Intel® IPP) is a cross-architecture software library that provides a range of library functions for multimedia, audio codecs, video codecs, image processing, signal processing, speech compression, cryptography, and computer vision, as well as math-support routines for such processing capabilities.
Performance Optimization Tools
The following tools enable performance optimization of the ported application:
Intel® Compilers are a vital component of software-performance optimization. The Intel® C++ Compiler and the Intel® Fortran Compiler support Windows* and Linux* will provide Intel® 64 support beginning with version 8.1.
Intel® VTune™ Performance Analyzer help developers and performance engineers to identify and correct software-performance bottlenecks. The VTune Analyzer will provide Intel® 64 support beginning with version 7.2 for Windows* and version 3.0 for Linux*.
Intel® Performance Libraries provide pre-optimized library functions. Future versions of the Intel® Math Kernel Library and Intel® Integrated Performance Primitives (Intel® IPP) will soon provide Intel® 64 support.
Tools for Troubleshooting
The following tools enable troubleshooting of the ported application (users should check with individual tool vendors for details about Intel® 64 support):
WinDbg* - native debugging along with NTSD and KD
DevPartner 64* - SoftICE and BounceChecker for Itanium de-bugging and error trapping
Driver Verifier - part of operating system
Depends* - Dependency Walker Debugging tool
Sysinternals* - 64-bit versions of the NTFilemon and NTRegmon file and registry monitors.
Porting applications to Intel's 64-bit operating environments – the Intel® Itanium® Processor Family and Intel® 64 architecture – can be seamless. Identifying the challenges beforehand and assembling all the supporting information, software, and tools can provide for a smooth migration. The available arsenal of tools, support personnel, and support Web sites from Intel and others not only complement the porting process but serve to facilitate it.
Assessing and Sizing an Itanium® Processor Family Porting Effort provides information to support porting projects of 32-bit code to the Intel Itanium Processor Family.
The Intel® 64 and IA-32 Architectures Software Developer's Manuals are an exhaustive programmer reference that provides development guidelines, a complete instruction-set reference and software-optimization strategies for Intel® 64.
Intel® Software Partner Program provides solutions to those who want to port their applications to the Intel Itanium Processor Family but do not have resources.
Prctl*, is a Linux* misalignment-identification tool from Hewlett-Packard's Unix System Enablement Laboratory.
Work from the following sources contributed to the preparation of this article:
Software Engineering Economics, Dr. Barry W Boehm
Software Engineering Directorate, Redstone Arsenal (Life Cycle Support Center)