by Armando Alcantar and Sreekanth Reddy Keesara
Porting to Itanium® 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 the 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. Mainstream languages that are typically ported are C++ and C. The effort focuses on Windows* but is relevant to the other flavors of UNIX. (BSD*, SCO*, Linux*, HP-UX*, Solaris*)
The following provides an overview of the phases involved in the porting process which provides a better understanding of the possible pitfalls.
Understand the Scope of the Porting Effort
At the onset of any porting effort, two primary items should be considered:
- Whether the porting projection is based on Lines of Source Code (LOSC).
- Whether the porting projection is based on the functionality of the application, i.e., translating baseline functionality, enhancements and legacy compatibility.
The two are different in scope of effort, time requirement, customer interface, manpower requisites, and deliverable schedules. Conventionally, Software Developers have attempted to scope migration effort by considering:
- conversion of 32-bit data types to 64-bit data types
Examples: Windows constructs are P64 (64-bit pointer model with 32-bit longs). Linux and HP-UX work on a LP64 (Longs and pointers are 64-bits)
- inclusion of specific Microsoft header files, however in the case of the many flavors of UNIX, developers can write batch/shell scripts for setting the build environment. If the Intel compiler is used, eclvars.bat or eclvars.sh can made use of.
- modification of compiler options, reference the Intel compilers options link
- identification of environment variables
- mapping of path-ways, and
- subsequent linking of supporting libraries and DLLs.
The projections on the completion of a porting effort are based on the precept that the porting effort is based on total lines of code. These efforts require a short learning curve, have a simplified porting effort, have a short-term deliverable schedule, and may not use a full complement of developmental tools.
Porting based on functionality of the application requires proprietary application knowledge, application functionality, access to customer developmental tools, and alignment of deliverables schedules. These factors have a greater impact on any 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 blo cks 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 have to be identified beforehand. The functionality of the commercially available application software must not be compromised.
It is important to understand whether these dependencies are sharing the same process space or not. The Itanium 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 is misleading. Embedded in this task is the mapping of requirements 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 these is expected to have an impact on 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, (typically accounting for sick days).
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
In the build process, many of the following items can be mitigated. Nonetheless, these items should 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.
The pseudo-build is delivered for final linking. Command-line and Visual Studio* environment incompatibilities must be identified. Compiler options, Microsoft Foundation Classes (MFCs) 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. The exclusion of the Intel® Compiler may not only impact nominal performance, but it may also impact the project's success in attaining a specific performance threshold. 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 on 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 64-bit Windows*, the following challenges exist:
- Alignment errors
- Pointers: handles, structs, packing and the rest; pointers used as I nt
- Data width
- Primary Issues the compiler doesn’t see
- Sloppy coding (e.g., mixing Dword and Long)
- Polymorphic misusage (e.g., using Dword/PSTR on same data)
- Handles: truncation by cast and by assignment
- Malloc: pThing = malloc ( sizeof ( LONG * ));
Developmental Challenges for Win64 bit port:
- Alignment errors, on Windows platforms, any misalignments will result in a system failure, but in UNIX it might result in poor performance. To identify misalignments and to minimize such performance degradation, there are some tools available.
- Pointers: handles, structs, packing, Int_ptr Malloc: pThing = malloc ( sizeof ( LONG * ));
- Data width
- Primary Issues the compiler doesn't see
- Sloppy coding: mixing Dword and Long
Note: DWORD and LONG are the same size on Windows but not on UNIX. On UNIX the compiler should see this.
- Polymorphic misusage (use Dword/PSTR on same data). Polymorphic Data Types are data types that are type-independent. Examples: size_t, Int_ptr
- Handles: truncation by cast and by assignment
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 they do not have control. When drafting a timeline or schedule, engineering judgment should be exercised 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; they should be identified in preliminary discussions.
Many current software applications have dependencies on other software/driver/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 advised to split them into three groups:
- The first group consists of non-native applications/drivers/agents that are performance-critical and hence need to be ported natively.
- The second group is that of non-native applications/drivers/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. As sess 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.
Consider end-user inputs in the planning, designing, and actual porting of the application. 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.
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, customers, would be beneficial in developing a robust application.
The software development life-cycle requires that validation and verification of the application be conducted. This should be done 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 the application performance. They support the latest of the platforms from Intel like Pentium® M processor and Itanium® processor along with improved Linux source compatibility and interoperability with gcc ABI 3.2 and "C" binary mix/match with gcc. Microsoft .Net Compilers are also used for this phase but they do not have some switches for processor specific optimizations. "Lint" is a valuable tool that can be utilized with UNIX ports.
There are some other tools that can be used in the "clean compile" phase; however we need to have in-depth knowledge of the application code and compiler options. These are Linux emulators like Cygwin*, and rules-based development tools like Parasoft*.
Intel® VTune™ Analyzer 7.1 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 which provides a range of library functions for multimedia, audio codecs, video codecs, image processing, signal processing, speech compression, cryptography plus 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:
- Compiler Options:
- LTCG (Link Time Code Generation)
- POGO (Profile Guided Optimization)
- Intel® VTune™ Performance Analyzer
- Intel® Performance Libraries
Tools for Troubleshooting
The following tools enable troubleshooting of the ported application:
- VS7 Native Debugger: comes with SDK
- 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 to Itanium® 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, Intel and other support websites not only complement the porting process but serve to facilitate it. The above topics are presented as a guide for software developers who intend to port applications to Itanium® platforms.
Related Links: Tools
- Intel Premier Support Web Site (requires login)
- Cygwin Linux Emulator*
- Parasoft rules-based development tool*
- Want to port to IPF but do not have resources? Join the Intel® Software Partner Program
- Intel® Itanium® Architecture Software Developer's Manual
- Intel® Performance Libraries
- Intel® Compilers
- Linux misalignment identification tools*
*Software Engineering Economics, Dr. Barry W Boehm
*Software Engineering Directorate, Redstone Arsenal (Life Cycle Support Center)