- Programming Guide for 64-bit Windows
- Benefits of 64-bit Windows
- 64-разрядные приложения 64-bit Applications
- Запуск 32- и 64-разрядных приложений в Windows Running 32-bit vs. 64-bit Applications on Windows
- Общие сведения о 64-разрядном программировании General 64-Bit Programming Information
- Поддержка создания 64-разрядных приложений компилятором Compiler Support for Creating 64-Bit Applications
- ГЛАВА 16
- Нынешнее состояние Win64
- Поддержка процессоров
- Поддержка Windows
- Поддержка сторонних компаний
- Обзор 64-разрядной архитектуры
- Необходимость в 64-битовой адресации
- Опыт UNIX
- Опыт перехода от 16-разрядных версий Windows к 32-разрядным
- Надолго ли хватит 64 бит?
- Модель программирования Win64
- Типы данных
- Типы данных фиксированной точности
- Типы данных, соответствующие точности указателей
- Пример: использование указательных типов данных
Programming Guide for 64-bit Windows
Microsoft has released 64-bit versions of the Windows operating system. 64-bit Windows was designed with compatibility in mind. Developers can ensure that their existing 32-bit applications run well under 64-bit Windows or take advantage of the benefits of 64-bit Windows by migrating their applications.
Benefits of 64-bit Windows
A 64-bit operating system supports far more physical memory than a 32-bit operating system. For example, most 32-bit Windows systems support a maximum of 4 gigabytes of physical memory, with up to 3 gigabytes of address space for each process, while 64-bit Windows supports up to 2 terabytes of physical memory with 8 terabytes of address space for each process. The increased physical memory includes the following benefits for applications:
- Each application can support more users. All or part of each application must be replicated for each user, which requires additional memory.
- Each application has better performance. Increased physical memory allows more applications to run simultaneously and remain completely resident in the system’s main memory. This reduces or eliminates the performance penalty of swapping pages to and from disk.
- Each application has more memory for data storage and manipulation. Databases can store more of their data in the physical memory of the system. Data access is faster because disk reads are not necessary.
- Applications can manipulate large amounts of data easily and more reliably. Video composition for motion picture work requires 64-bit Windows for this reason. Modeling for scientific and financial applications benefits greatly from memory-resident data structures that are not possible on 32-bit Windows.
There are also important benefits for businesses:
- Increased productivity. Knowledge workers can spend their time thinking and producing, rather than waiting for the software to finish its tasks.
- Lower cost of ownership. Each server can support larger numbers of users and applications, so your business will require fewer servers. This translates directly into less management overhead—one of the highest costs in any computing environment.
- New application opportunities. New applications can be designed without the barriers imposed by 32-bit Windows. New graphics applications will make work easier and more enjoyable. Data-intensive tasks that are impossible today can be done with 64-bit Windows.
64-разрядные приложения 64-bit Applications
При компиляции приложения можно указать, должно ли оно запускаться в 64-разрядной операционной системе Windows в качестве собственного приложения или в эмуляторе WOW64 (в 32- или 64-разрядной ОС Windows). When you compile an application, you can specify that it should run on a Windows 64-bit operating system either as a native application or under WOW64 (Windows 32-bit on Windows 64-bit). WOW64 — это среда совместимости, которая позволяет выполнять 32-разрядное приложение в 64-разрядной системе. WOW64 is a compatibility environment that enables a 32-bit application to run on a 64-bit system. Эмулятор WOW64 входит в состав всех 64-разрядных версий операционной системы Windows. WOW64 is included in all 64-bit versions of the Windows operating system.
Запуск 32- и 64-разрядных приложений в Windows Running 32-bit vs. 64-bit Applications on Windows
Все приложения, построенные на платформе .NET Framework версий 1.0 и 1.1, обрабатываются в 64-разрядной операционной системе как 32-разрядные приложения и всегда запускаются в эмуляторе WOW64 и в 32-разрядной среде CLR. All applications that are built on the .NET Framework 1.0 or 1.1 are treated as 32-bit applications on a 64-bit operating system and are always executed under WOW64 and the 32-bit common language runtime (CLR). 32-разрядные приложения, созданные на платформе .NET Framework 4 или более поздних версий, также выполняются в эмуляторе WOW64 в 64-разрядных системах. 32-bit applications that are built on the .NET Framework 4 or later versions also run under WOW64 on 64-bit systems.
Visual Studio устанавливает на компьютер с архитектурой x86 32-разрядную версию среды CLR, а на компьютер с 64-разрядной ОС Windows — 32-разрядную и соответствующую 64-разрядную версию среды CLR. Visual Studio installs the 32-bit version of the CLR on an x86 computer, and both the 32-bit version and the appropriate 64-bit version of the CLR on a 64-bit Windows computer. (Так как среда Visual Studio является 32-разрядным приложением, то при установке в 64-разрядной системе она выполняется в эмуляторе WOW64.) (Because Visual Studio is a 32-bit application, when it is installed on a 64-bit system, it runs under WOW64.)
Из-за особенностей эмуляции x86 и подсистемы WOW64 для процессоров семейства Itanium выполнение приложений ограничено одним процессором. Because of the design of x86 emulation and the WOW64 subsystem for the Itanium processor family, applications are restricted to execution on one processor. Эти факторы снижают производительность и масштабируемость 32-разрядных приложений .NET Framework, выполняемых в системах на базе Itanium. These factors reduce the performance and scalability of 32-bit .NET Framework applications that run on Itanium-based systems. Для повышения производительности и масштабируемости рекомендуем использовать версию .NET Framework 4 со встроенной поддержкой 64-разрядных систем на базе Itanium. We recommend that you use the .NET Framework 4, which includes native 64-bit support for Itanium-based systems, for increased performance and scalability.
При запуске 64-разрядного управляемого приложения в 64-разрядной операционной системе Windows по умолчанию можно создавать объекты размером не более 2 гигабайт (ГБ). By default, when you run a 64-bit managed application on a 64-bit Windows operating system, you can create an object of no more than 2 gigabytes (GB). Однако в .NET Framework 4.5 это ограничение можно повысить. However, in the .NET Framework 4.5, you can increase this limit. Дополнительные сведения см. в описании элемента . For more information, see the element.
Многие сборки выполняются в 32- и 64-разрядной среде CLR одинаково. Many assemblies run identically on both the 32-bit CLR and the 64-bit CLR. Однако в зависимости от версии среды CLR работа некоторых программ может отличаться по одной из следующих причин: However, some programs may behave differently, depending on the CLR, if they contain one or more of the following:
структуры, содержащие члены, размер которых меняется в зависимости от платформы (например, любой тип указателя); Structures that contain members that change size depending on the platform (for example, any pointer type).
Арифметика указателя, содержащая постоянные размеры. Pointer arithmetic that includes constant sizes.
Неверный вызов платформ или объявления СОМ, использующие дескрипторы Int32 вместо IntPtr . Incorrect platform invoke or COM declarations that use Int32 for handles instead of IntPtr .
приведение IntPtr к Int32 . Code that casts IntPtr to Int32 .
Дополнительные сведения о переносе 32-разрядного приложения в 64-разрядную среду CLR см. на странице Миграция 32-разрядного управляемого кода в 64-разрядную систему. For more information about how to port a 32-bit application to run on the 64-bit CLR, see Migrating 32-bit Managed Code to 64-bit.
Общие сведения о 64-разрядном программировании General 64-Bit Programming Information
Общие сведения о 64-разрядном программировании см. в перечисленных ниже материалах. For general information about 64-bit programming, see the following documents:
В документации по Windows SDK см. статью Programming Guide for 64-bit Windows (Руководство по программированию для 64-разрядных версий Windows). In the Windows SDK documentation, see Programming Guide for 64-bit Windows.
Сведения о поддержке создания 64-разрядных приложений в Visual Studio см. в разделе Поддержка 64-разрядной среды разработки Visual Studio. For information about Visual Studio support for creating 64-bit applications, see Visual Studio IDE 64-Bit Support.
Поддержка создания 64-разрядных приложений компилятором Compiler Support for Creating 64-Bit Applications
Приложение, построенное с помощью .NET Framework на 32- или 64-разрядном компьютере, на 64-разрядном компьютере по умолчанию выполняется как собственное приложение (не в эмуляторе WOW64). By default, when you use the .NET Framework to build an application on either a 32-bit or a 64-bit computer, the application will run on a 64-bit computer as a native application (that is, not under WOW64). В таблице ниже перечислены материалы, в которых описывается использование компиляторов Visual Studio для создания 64-разрядных приложений, выполняемых как собственные, в эмуляторе WOW64 или обоими способами. The following table lists documents that explain how to use Visual Studio compilers to create 64-bit applications that will run as native, under WOW64, or both.
ГЛАВА 16
Программирование в среде Win64
Наиболее заметный прогресс в развитии возможностей Windows после появления Windows NT и Windows 95 связан с приходом 64-разрядного программирования и расширением Win32 до Win64. На объединенный API обычно ссылаются просто как на Windows API, и именно такой практики мы придерживались на протяжении всей книги. API Win64 обеспечивает возможность выполнения в Windows наиболее крупных и требовательных в отношении ресурсов приложений уровня предприятий и приложений для научных расчетов. 64-разрядные системы позволяют программам использовать гигантские адресные пространства, которые выходят далеко за предел 4 Гбайт, обусловленный 32-битовой адресацией.
В данной главе описано нынешнее состояние Win64 и преимущества этого интерфейса, а также рассмотрена соответствующая модель программирования и обсуждены вопросы переносимости программ между различными операционными системами и аппаратными платформами. Это рассмотрение проводится безотносительно к фактическому типу 64-разрядного процессора или конкретной версии Windows, обеспечивающих поддержку Win64. Процесс переноса одного из предыдущих примеров иллюстрирует программа 16.1.
Нынешнее состояние Win64
В данном разделе анализируется состояние поддержки компанией Microsoft интерфейса Win64 на различных системах и процессорах, сложившееся к концу первого полугодия 2004 года. Поскольку ситуация постоянно меняется, приведенную ниже информацию следует рассматривать лишь в качестве «моментального снимка» реального положения дел. Тем не менее, на охватываемых здесь аспектах программирования эволюция поддержки Win64 никак не сказывается.
По-видимому, в будущем мы окажемся свидетелями значительного прогресса и изменений в этой области, хотя внедрение Win64 происходит довольно-таки медленно. Приведенная ниже информация почерпнута, как правило, на Web-сайтах соответствующих поставщиков и из отраслевых изданий, так что для получения впоследствии более свежих данных вы можете воспользоваться этими же источниками.
Поддержка процессоров
Win64 поддерживается или, о чем можно говорить почти с полной уверенностью, будет поддерживаться, по крайней мере, на трех различных семействах процессоров:
• Семейство процессоров Itanium (Itanium Processor family, IPF) компании Intel, архитектура которых полностью отличается от известной архитектуры Intel x86. IPF предоставляет большие регистровые файлы (включающие 128 регистров общего назначения), каналы многоадресных команд, встроенные трехуровневые кэши, а также множество других средств, обеспечивающих высокую производительность и 64-битовую адресацию. В настоящее время на рынок поставляются процессоры Itanium 2, и хотя их предшественник — процессор Itanium — является теперь уже устаревшим, нам будет удобно ссылаться на все семейство просто как на «процессоры Itanium».
• Процессоры Opteron и Athlon 64 (AMD64) компании AMD, предназначенные, соответственно, для серверов и рабочих станций. Архитектуру AMD64 можно рассматривать как расширение архитектуры Intel x86, допускающее 64-битовую виртуальную адресацию и параллельное выполнение 32– и 64-битовых операций.
• 32/64-разрядные процессоры компании Intel, сравнимые с процессорами AMD64. Во время написания этой книги ожидалось, что технология 64-разрядного расширения будет применена в первую очередь в процессорах Xeon. Как и прогнозировалось, такие процессоры появились на рынке в конце 2004 года.
Поддержка Windows
API Win64 компании Microsoft предназначен для поддержки 64-разрядных архитектур таким способом, при котором в существующие исходные и двоичные коды требуется вносить лишь минимальные изменения. В настоящее время имеется несколько отдельных версий Win64.
• Windows XP 64-bit Edition доступна в виде, по крайней мере, двух версий. Бета-версия компании Microsoft поддерживает только процессор AMD Opteron. Компания Hewlett Packard выводит на рынок несколько моделей рабочих станций на базе процессоров Itanium с уже установленной системой Windows XP-Itanium2.
• Windows Server 2003 Enterprise Edition for 64-bit Extended Systems в настоящее время также проходит бета-тестирование. Эта версия обеспечивает поддержку процессоров AMD Opteron и Intel Xeon с использованием технологии 64-разрядного расширения.
• Windows Server 2003 Enterprise Edition for 64-bit Itanium-based Systems поддерживает, как говорит само ее название, серверы и рабочие станции, использующие один или несколько процессоров Itanium. Существует также версия Datacenter Edition. Например, эта версия устанавливается на системах Integrity компании Hewlett Packard, которые в настоящее время также появляются на рынке.
Поддержка сторонних компаний
На платформе Win64 доступны многочисленные базы данных, математические библиотеки, прикладные системы уровня предприятия, системы с открытым исходным кодом, а также целый ряд других систем. Тем не менее, каждый раз, когда планируется перенос программ на эту платформу, доступность необходимых продуктов сторонних компаний должна предварительно проверяться.
Обзор 64-разрядной архитектуры
С точки зрения программиста основная трудность при переходе от 32-разрядной модели к 64-разрядной заключается в том, что размер указателей и таких системных типов данных, как size_t и time_t, теперь может составлять 64 бита. Поэтому виртуальное адресное пространство процесса уже не ограничивается 4 Гбайт (фактически доступны приложениям только 3 Гбайт). Таким образом, перенос программ из Win32 в Win64 по существу требует лишь «удлинения» указателей, с чем связаны лишь самые минимальные последствия для пользовательских данных в модели Windows.
Необходимость в 64-битовой адресации
Возможности доступа к большим адресным пространствам требуются многим приложениям. Можно было бы привести множество примеров, аналогичных тем, которые перечислены ниже.
• Приложения для обработки изображений. Системы, использующие адресные пространства размером 4 Гбайт, в состоянии обеспечить лишь 20-секундное воспроизведение телевизионного изображения высокой четкости (High-Definition Television, HDTV) в реалистичных цветах.
• Автоматизированное проектирование механических (Mechanical Computer-Aided Design, MCAD) и электронных (Electronic Computer-Aided Design, ECAD) устройств. Для проектирования сложных сборочных узлов требуется наличие более 3 Гбайт памяти, а проектирование микросхем предъявляет к памяти несоизмеримо более высокие требования.
• Базы данных и хранилища данных. Использование файлов с размерами в несколько сотен Гбайт не является чем-то необычным, и возможность доступа к виртуальным адресным пространствам сопоставимых размеров значительно упрощает обработку таких файлов.
Теперь поддержка подобных запросов в отношении адресных пространств большого объема стала реальностью. Пройдет совсем немного времени, и 64-разрядные микропроцессоры станут доступными каждому, а большие объемы физической памяти при разумной стоимости будут поддерживаться на многих системах.
Потребность в 64-битовой адресации диктуется теми же факторами, которые делают столь желательными и необходимыми файлы гигантских размеров (свыше 4 Гбайт), и теперь, когда имеются достаточно мощные микропроцессоры Itanium, AMD64, а также процессоры, использующие технологию 64-разрядного расширения, вполне естественно ожидать, что Windows должна будет эволюционировать для удовлетворения этих запросов. Использование 64-разрядных ОС существенно в тех случаях, когда Windows отводится заметная роль в прикладных корпоративных и профессиональных системах.
Тем не менее, многие 32-разрядные приложения смогут работать нормально и на новой платформе, и на первом этапе для их переноса не надо будет ничего предпринимать. Для таких персональных приложений, как Microsoft Office или Adobe PageMaker, в течение некоторого времени переход к 64-битовой адресации, по-видимому, не потребуется. Следовательно, Windows будет поддерживать обратную совместимость.
Как и следовало ожидать, применение существующих 64-разрядных процессоров часто обеспечивает выигрыш в производительности, но этот выигрыш непосредственно никак не сказывается на программировании на уровне исходного кода.
Опыт UNIX
PC-системы всегда отставали от универсальных вычислительных систем (мэйнфреймов) и систем на основе UNIX в том, что касается базовых функциональных возможностей и масштабируемости. То же самое остается справедливым и в случае 64-разрядных архитектур.
• Основные поставщики UNIX-систем предоставляют 48– и 64-разрядные микропроцессоры с начала 90-х годов прошлого столетия.
• Основные поставщики UNIX-систем поддерживают 64-разрядные API на протяжении примерно того же периода времени.
• Сообщество пользователей UNIX остановилось на выборе в качестве стандарта так называемой модели LP64, отличающейся от модели Р64, принятой в Win64, о чем далее еще будет говориться.
• Переходы от 32 к 64 битам всегда осуществлялись сравнительно простым, если не сказать — тривиальным образом, и можно ожидать, что то же самое будет наблюдаться и при переходе от Win32 к Win64.
Опыт перехода от 16-разрядных версий Windows к 32-разрядным
Переход от 16-разрядных версий Windows к 32-разрядным начался в начале 90-х годов прошлого столетия с появлением Windows NT, и набрал ускорение после того, как использование Windows 95 стало обычным делом. Каким бы соблазнительным ни казалось предположение о том, что нас ожидает повторение той же истории, рассматриваемые нами ситуации отличаются в нескольких аспектах.
• Windows NT и Windows 95 были первыми из широко используемых «реальных» операционных систем для PC в том смысле, что обе системы поддерживали обмен страницами по запросу, потоки, вытесняющую многозадачность и множество других возможностей, которые были описаны в главе 1.
• Хотя API Win32 значительно расширил полезное адресное пространство, что делает и Win64, усовершенствования этим не ограничивались. Неуклюжие и устаревшие, несмотря на свою популярность, модели расширенной памяти были заменены другими. Аналогичная модель расширенной памяти (не описывается в данной книге) была введена и в Windows 2000, однако общие последствия этого шага в данном случае были не столь существенными.
• В API Win32 было введено множество новых функциональных возможностей, чего нельзя сказать о Win64.
Надолго ли хватит 64 бит?
Что касается мира PC, в котором возникла Windows, то можно утверждать, что первоначальная 16-разрядная модель Intel x86 (фактическое адресное пространство которой является 20-битовым) просуществовала в течение более десяти лет, и столько же времени уже существует и 32-разрядная архитектура. Однако переход к Win64 и 64-разрядному программированию, вообще говоря, происходит медленнее, чем происходил аналогичный переход к 32 битам. Вместе с тем, в обоих случаях переход миникомпьютеров и серверов на следующий уровень осуществлялся, по крайней мере, за 10 лет до того, как это начинало происходить с PC. Тогда вполне естественно задаться вопросом о том, следует ли ожидать перехода серверов или PC к 128 битам в будущем. Берусь утверждать, что любое расширение такого рода произойдет не раньше, чем через 10 лет, исходя из одной лишь величины 64-разрядного адресного пространства.
Предсказания — вещь ненадежная, однако, воспринимая это серьезно лишь наполовину, можно напомнить о часто цитируемом законе Мура, согласно которому отношение «стоимость/производительность» уменьшается вдвое каждые 18 месяцев. В свою очередь, быстродействие и емкость устройств каждые 18 месяцев примерно удваиваются. Применяя эти рассуждения к адресному пространству, можно ожидать, что дополнительный бит адреса нам будет требоваться через каждые 18 месяцев, откуда следует, что 64-разрядная модель будет исправно служить еще целых 48 лет (то есть почти столько же времени, сколько насчитывает вся история современных компьютеров). Оправданы ли такие неформальные выводы, которые встретились мне в одном из официальных источников, покажет время, однако в прошлом запросы к ресурсам PC возрастали гораздо быстрее, чем утверждается в приведенном прогнозе.
Модель программирования Win64
В зависимости от выбора способа представления таких стандартных типов данных С, как указатели и целочисленные типы данных (long, int и short), a также от того, вводятся или не вводятся нестандартные типы данных, возможны несколько вариантов модели 64-разрядного программирования. Напомним, что в стандарте ANSI С размеры типов данных не определяются строго, хотя и требуется, чтобы размер данных типа long int был не меньше размера данных типа int, а размер данных типа int был не меньше размера данных типа short int.
Цель состоит в том, чтобы ввести единое определение Windows API (то есть, общее для Win32 и Win64), благодаря чему можно будет использовать единый базовый исходный код. Использование этого единого определения может потребовать внесения некоторые изменений в исходный код, но эти изменения должны быть сведены к минимуму.
Microsoft выбрала модель LLP64 (целые числа типа long и 64-битовые указатели), на которую обычно ссылаются просто как на модель Р64. В частности, существуют следующие определения типов данных, применимые как к данным со знаком, так и к данным без знака:
• char — 8 бит, и wchar — 16 бит.
• long int — также 32 бита.
• Размер указателя любого типа, например PVOID, составляет 64 бита.
Для тех случаев, когда требуются данные строго определенного размера, предусмотрены дополнительные типы данных. Так, компилятор Microsoft различает следующие типы данных: _int16, _int32 и _int64.
Типы данных
Приведенные в этой главе таблицы взяты непосредственно из оперативной справочной системы и представляют единую модель данных Windows (Windows Uniform Data Model). Определения типов можно найти в заголовочном файле BASETSD.H, входящем в состав интегрированной среды разработки приложений Microsoft Visual Studio .NET (версия 7.0) и версию 6.0 этой системы.
Типы данных фиксированной точности
Обозначения типов данных фиксированной точности получаются из обычных обозначений типов данных Win32, таких как DWORD или LONG, добавлением суффикса размера, как показано в табл. 16.1.
Таблица 16.1. Типы данных фиксированной точности
Тип данных | Описание |
---|---|
DWORD32 | 32-битовое целое без знака |
DWORD64 | 64-битовое целое без знака |
INT32 | 32-битовое целое со знаком |
INT64 | 64-битовое целое со знаком |
LONG32 | 32-битовое целое со знаком |
LONG64 | 64-битовое целое со знаком |
UINT32 | Целое типа INT32 без знака |
UINT64 | Целое типа INT64 без знака |
ULONG32 | Целое типа LONG32 без знака |
ULONG64 | Целое типа LONG64 без знака |
Типы данных, соответствующие точности указателей
Процитируем выдержку из статьи Microsoft под названием «The New Data Types» (доступна на Web-сайте компании Microsoft): «Точность этих типов данных отражает изменение точности указателей (то есть, они становятся 32-битовыми в коде Win32 и 64-битовыми в коде Win64). Поэтому приведение указателей к одному из этих типов при выполнении арифметических операций с указателями является безопасным; при 64-битовой точности указателей размер данных этого типа будет составлять 64 бита. Также и типы данных, соответствующие счетчикам, отражают максимальный размер данных, на которые может ссылаться указатель.» Таким образом, эти типы данных обеспечивают автоматическое изменение размеров целочисленных типов данных в зависимости от изменения размеров указателей, в связи с чем их иногда называют полиморфными (polymorphic data types) или платформо-масштабируемыми (platform scaled data types) типами данных. Типы данных, соответствующие точности указателей, перечислены в табл. 16.2, взятой из той же статьи.
Наиболее важным из них является тип данных SIZE_T, который уже использовался нами при описании размеров блоков памяти в главе 5.
Наконец, заметьте, что в Win64 размер данных типа HANDLE составляет 64 бита.
Таблица 16.2. Типы данных, соответствующие точности указателей
Тип данных | Описание |
---|---|
DWORD_PTR | Длинное целое без знака, соответствующее точности указателей. |
HALF_PTR | Половина размера указателя. Используется в структурах, содержащих указатель и два поля небольшого размера. |
INT_PTR | Целое со знаком, соответствующее точности указателей. |
LONG_PTR | Длинное целое со знаком, соответствующее точности указателей. |
SIZE_T | Максимальное количество байтов, на которые может ссылаться указатель. Используется для счетчиков, которые должны охватывать весь диапазон возможных значений указателей. |
SSIZE_T | Тип SIZE_T со знаком. |
UHALF_PTR | Тип HALF_PTR без знака. |
UINT_PTR | Тип INT_PTR без знака. |
ULONG_PTR | Тип LONG_PTR без знака. |
Пример: использование указательных типов данных
Аргументом потока, передаваемым функции потока при вызове CreateThread и _beginthreadex (см. главу 7), является указатель типа PVOID. Иногда программист может захотеть передать функции потока только целочисленное значение, указывающее, например, номер потока или индекс данных в глобальной таблице. Тогда функцию потока, интерпретирующую параметр как целое без знака, можно было бы написать следующим образом:
DWORD WINAPI MyThreadFunc(PVOID Index_PTR) <