Как выделить одному приложению 5 ГБ памяти?
От: Skipper_N  
Дата: 30.12.07 17:29
Оценка:
Чтобы работало мое приложение (алгоритм) — нужно 5 ГБ памяти, меньше никак.

Казалось бы, я уже ВСЕ ВОЗМОЖНОЕ для этого сделал... Купил 4 планки по 2 гигабайта каждая.
Процессор 64-разрядный (Athlon 64 4000+ ). Именно 64-разрядный проц нужен для того, чтобы поставить 64-разрядную ОС. Я поставил Windows Professional x64 Edition. Windows "видит" всю память — в Task Manager-e отображается вся — 8 ГБ. Именно 64-разрядная ОС должна быть, чтобы создавать 64-разрядные приложения и "стал" 64-разрядный компилер. Я поставил MS Visual Studio 2005 Professional. Там есть 64-разрядный компилятор и можно выбрать опцию — компилировать не для Win32 (это по умолчанию), а для x64.

Я проверил — создано действительно 64-разрядное приложение "по всем статьям", так сказать. Т.е. оно в обычной 32-разрядной Windows не выполняется, при дизассемблировании вижу, что арифм. операции с 64-разрядными int выполняются за 1 машинную инструкцию (чего нет в 32-разрядных), также длина указателей стала не 32 бита (4 байта), как раньше, типа 0x7fffffff, а 64 бита (8 байт) — например 0x000000012d265000.

Зачем нужны были эти все шаги? Все просто — 32-разрядное приложение не может адресовать более 4 гигабайта оперативной памяти (2 в степени 32 — даст около 4 млрд байт), а на деле — не более 3 гигабайт винда даст адресовать. Для 64-разрядных приложений предел вообще порядка 10^18 степени байт, и я понимаю, что можно ввести какие-то ограничения, НО ЗАЧЕМ ДЕЛАТЬ ТАКИЕ ЖЕ ОГРАНИЧЕНИЯ, КАК И ДЛЯ 32-РАЗРЯДНОЙ -- 3 ГБ ??

В приложении выделил свои 5 ГБ — скомпилировал, ошибки нет, но в Task Manager-e показано, что приложению выделено только 3 ГБ примерно. Какой же тогда смысл переходить на 64-разрядную архитектуру, и какой смысл в таких указателях — 0x000000012d265000, если много нулей не используется? Начал инициализировать этот выделенный 5-гигабайтный массив — и точно, после того как прошел примерно 3 ГБ, вылетела ошибка.

Если приложение под CLR — то вылетает —
An Unhandled exception of type 'System.AccessViolationException' occured in ...exe
Additional Information: Attempted to read or write protected memory. This is often an indication that other memory
is corrupt.

Если же приложение под MFC — то вылетает —
Unhandled exception at 0x004065ed in WMFC3264.exe: 0xC0000005: Access violation reading location

0x000000012d265000.

Т.е. то ли в студии нужно разрешить больше памяти использовать в heap (такая опция была в Borland C++ Builder помню), но поискав в опциях проекта — ничего подобного не нашел, то ли в Windows есть ограничение на выделение памяти одному приложению. Попробовал изменить параметры винды в My Computer — Properties — Advanced — Performance Setting — Advanced — результата никакого. Может, есть еще какие-нибудь настройки в винде или студии?


Как справиться с такой проблемой? Неужели до сих пор нельзя выделить памяти 5 ГБ одному приложению ? Я шокирован буду если так... На дворе 2008 год наступает...

02.01.08 10:20: Перенесено из 'Архитектура программного обеспечения'
Re: Как выделить одному приложению 5 ГБ памяти?
От: SergH Россия  
Дата: 30.12.07 18:10
Оценка:
Здравствуйте, Skipper_N, Вы писали:

S_N> Чтобы работало мое приложение (алгоритм) — нужно 5 ГБ памяти, меньше никак.


Как память выделяешь? VirtualAlloc[Ex] попробуй.
Делай что должно, и будь что будет
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Skipper_N  
Дата: 30.12.07 18:19
Оценка:
Здравствуйте, SergH, Вы писали:

SH>Как память выделяешь? VirtualAlloc[Ex] попробуй.


Программа на С++ и память для массива выделяется обычным, стандартным оператором new .
Что такое VirtualAlloc[Ex] и с чем его едят?

И еще вопрос. Если Вы думаете, что дело в типе выделения, то Вы думаете, что проблема не в операционке?
Мне почему-то казалось, что возможно, винда не дает приложению более 3 ГБ.
Re[3]: Как выделить одному приложению 5 ГБ памяти?
От: SergH Россия  
Дата: 30.12.07 18:26
Оценка:
Здравствуйте, Skipper_N, Вы писали:

S_N> Программа на С++ и память для массива выделяется обычным, стандартным оператором new .


Ага. Это значит, что для выделения памяти используется два уровня — апи операционной системы и куча C++. Проблема может быть как там, так и там.

S_N>Что такое VirtualAlloc[Ex] и с чем его едят?


Ну, про виртуальное пространство ты всё правильно писал, значит с понятием знаком. В виртуальном пространстве память резервируется страницами. VirtualAlloc[Ex] это функции выделения памяти самого низкого уровня — на уровне страниц виртуальной памяти. Все остальные неявно её используют. Я предлагаю использовать явно, т.е. написать свою небольшую кучу.

Подробнее про функцию — см MSDN.

S_N>И еще вопрос. Если Вы думаете, что дело в типе выделения, то Вы думаете, что проблема не в операционке?

S_N>Мне почему-то казалось, что возможно, винда не дает приложению более 3 ГБ.

Я не знаю. Я могу только предполагать. Я не работал с 64-х разрядной виндой.
Но, возможно, в данном случае дело в рантайме C++.
Делай что должно, и будь что будет
Re: Как выделить одному приложению 5 ГБ памяти?
От: Аноним  
Дата: 30.12.07 19:04
Оценка:
Приложение собирал как на VS 2005/XP так и на VS2005, VS2008/Vista x64 Ultimate. Из семейства винды, под запуск использовал только Vista x64 Ultimate. Все нормально. Чёй-то мне кажется, что дело в операционке.
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Аноним  
Дата: 30.12.07 19:30
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Приложение собирал как на VS 2005/XP так и на VS2005, VS2008/Vista x64 Ultimate. Из семейства винды, под запуск использовал только Vista x64 Ultimate. Все нормально. Чёй-то мне кажется, что дело в операционке.


У меня Windows XP Professional x64 Edition.

Приложение у меня собирается. Т.е. на new с выделением 5 гиг — не ругается (ругается только если собирать с Win32, а я собираю с x64).

Только вот в Task Manager-e показывает, что выделено всего около 3 ГБ. И когда начинаю использовать, инициализировать свой массив, то после прохода 3 ГБ — вылетает ошибка.


Вы можете подробнее расписать, что вы делали на VS 2005/XP , какой тип проекта, какие меняли настройки, и прошлись ли по всем 5 гигабайтам?
Re: Как выделить одному приложению 5 ГБ памяти?
От: Стэн http://stanonwork.blogspot.com/
Дата: 30.12.07 20:42
Оценка:
Здравствуйте, Skipper_N, Вы писали:

S_N> Чтобы работало мое приложение (алгоритм) — нужно 5 ГБ памяти, меньше никак.


S_N> [skipped]


Следующий код у меня как скомпилировался, так и отработал нормально...
Собирал под: WinXP (32bit), MS VS 2005 (x64).
Запускал: WinXP x64 (64bit), 2G RAM.

Может быть дело все таки не ввыделении памяти, а в алгоритме прохода по нему?
Или, можно предположить, что есть дефект в модуле памяти...

#include <cstddef>
#include <iostream>
#include <memory>
#include <conio.h>

// -
typedef unsigned char       byte;

// -
#define SIZE    (5 * 1024 * 1024 * 1024)


int main()
{
    {
        std::auto_ptr<byte>     array(new byte[SIZE]); 
        // -
        byte*   p = array.get();
        // -
        for (size_t i = 0; i < SIZE; i++) {
            *p++ = static_cast<byte>(i % 0x78);
        }
    }

    std::cout << ":end" << std::endl;
    _getch();

    return 0;
}
Re: Как выделить одному приложению 5 ГБ памяти?
От: Skipper_N  
Дата: 31.12.07 03:41
Оценка:
Позже выяснил, что приложение может выделить 5 ГБ и более. Просто new XXX[N] — для массивов с очень большим N — глючит. Это N еще зависит от типа XXX. Когда добавил еще один bitF2 = new BitF[350000000]; — то приложение отлично видело и инициализировало 5,5 ГБ памяти.

Словил ли я ошибку компилятора? Их же тестируют самым жестоким образом!

У кого стоит Windows XP Professional x64 Edition (либо любая 64-разрядная Windows), и стоит MS Visual Studio 2005 — можете проверить у себя. Действия примитивны:

1. Открываем Visual Studio 2005 — New Project — MFC Application — далее выбираем Dialog Based — тип приложения, остальное все по умолчанию.
2. Открываем Resource View, щелкаем двойным по IDD_ИмяПроекта_DIALOG, бросаем туда Button, щелкаем по нему двойным, и у нас появился обработчик OnBnClickedButton1()

3. В этот обработчик пишем:

----------------------
void CDDlg::OnBnClickedButton1()
{
int* p = new int[1250000000];
// длина int == 4 байта, поэтому длина массива 5 млрд байт


// пробег по 300 млн. int == пробегу по 1,2 млрд байт
for(int i = 0; i < 1000000000; i++)
{
p[i] = 1;
}

p[1] = 2; // сюда ставим брэкпоинт, если остановимся здесь, то по массиву пробежали успешно

}
----------------------

Понятное дело, что это не откомпилируется, выдаст ошибку на
int* p = new int[1250000000];
— ведь для 32-разрядных приложений нельзя адресовать 5 млрд байт памяти. Поэтому,

4. Делаем в тулбаре справа от написанного текста "Debug" — вместо "Win32" — "x64". (для этого в Configuration Manager, заходим в "Active Solution Platform", <New...>).

Теперь у нас 64-разрядное приложение, мы его компилируем и оно компилится. Нажимаем кнопку и попадаем на 1-й брэкпоинт. Т.е. у нас уже отработало new int[1250000000]; Должно быть у приложения уже 5 ГБ выделено, но Task Manager показывает нам, что выделено всего лишь 696 МЕГАБАЙТ !!! Поэтому, неудивительно, что сняв этот 1-й брэкпоинт и отпустив приложение, оно проработает недолго и выдаст ошибку. Это на 176259044 — й итерации (т.е. переменная i — дошла только до 176 259 044 — именно столько было в массиве выделено интов. Это и есть 696 мегабайт или около 700 млн БАЙТ).

Далее, интересное наблюдение. Если поменять одну строку и сделать int* p = new int[1000000000]; ,т.е выделение не 5 млрд байт, а ровно 4 млрд, то выделение срабатывает правильно, и программа выполняется без ошибок. Причем, когда я пытался выделить 1250000000, то он тоже МОГ бы выделить ХОТЯ БЫ 4 ГБ, но он вообще выделил только 700 мег. Значит, если new int[N] , где N — слишком большое (подозреваю, больше 1 млрд, т.е. 2^31), то компилятор ВМЕСТО ТОГО, ЧТОБЫ ВЫДАТЬ ОШИБКУ — ПРОСТО ВЫДЕЛЯЕТ НЕПРАВИЛЬНОЕ КОЛИЧЕСТВО ПАМЯТИ (от балды, так сказать).

Попробовал те же действия с __int64. Оно длиннее в 2 раза, поэтому при выделении new __int64[1000000000] — уже не правильно, как было в прошлый раз. Установил, что максимальное количество элементов __int64 массива, при которых память полностью правильно выделяется — 500 000 000 примерно. Т.е. при этом тоже будет выделено около 4 ГБ. Если больше, то — переполнение и ошибки.

Попробовал еще 2 варианта — со структурами, длиной 32 бита, 64 бит. Та же фигня — с 32-битными структурами получается выделить чуть больше 1 млрд, с 64-битными — 500 млн. И от чего эти лимиты зависят?? Почему с int можно задать бОльше элементов массива, чем с __int64 ?? Вроде, хотя процессу (64-разрядному) можно дать и хоть 10 ГБ, хоть 100 ГБ памяти, а вот НА ОДИН УКАЗАТЕЛЬ БОЛЬШЕ 4 ГБ ПОЛОЖИТЬ НЕЛЬЗЯ. (в нашем случае это был int* p).

Вот такое неожиданное открытие я сделал. В книжках, о том, сколько максимум способен выделить один new (4 ГБ) — почему-то не пишут... И пока у всех 32-разрядные платформы, никто этим не занимался. Но в будущем, возможно, когда будут 64-разрядные платформы, еще много кто сделает для себя такое открытие. Жалко только, что столько времени я на это потерял...
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Аноним  
Дата: 31.12.07 06:50
Оценка: +1
Здравствуйте, Skipper_N, Вы писали:

хорошее изыскание
только не верьте TaskManager
Если у вас такой "крутой" алгоритм — не пользуйтесь встроеным диспетчером памяти.
Как вам и советовали юзайте VirtualAlloc, и там уже будете выбирать сразу память коммитить (все 5 гигов съедать) или просто резервировать и вообще выделять ли 5 гигов.
Плюс почитайте что-нибудь по организации памяти.

Если "чукча не писатель чукча читатель", т.е. вы просто хороший алгоритмист, но не прикладник, то найдите человека который вам реализует ваш алгоритм. Но уж точно не следует идти простым new XXX, т.к.: а) стандартная куча RTL, на мой взгляд, не расчитана на эффективную работу с такими объёмами (как вариант можно свою кучу использовать, но лучше всё таки VirtualAlloc), б) в следующий раз ваш алгоритм может потребовать 12 гигов памяти, т.е. решение с new xxx не масштабируемо.
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: skeptik_  
Дата: 01.01.08 20:46
Оценка: +1
Skipper_N wrote:
> int* p = new int[1250000000];
> // длина int == 4 байта, поэтому длина массива 5 млрд байт
Я бы на твоём месте поостерёгся делать такие предположения.

> Попробовал те же действия с __int64.

Если уж ты хочешь интеджер определённой длины, то возьми
#include <cstdint>
uint64_t, int64_t и так далее. Если этого хедера нет в системе, то идём
сюда — http://www.boost.org/libs/integer/index.html.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Пётр Седов Россия  
Дата: 02.01.08 08:39
Оценка: +1
Здравствуйте, Стэн, Вы писали:

С>
С>#include <cstddef>
С>#include <iostream>
С>#include <memory>
С>#include <conio.h>

С>// -
С>typedef unsigned char       byte;

С>// -
С>#define SIZE    (5 * 1024 * 1024 * 1024)


С>int main()
С>{
С>    {
С>        std::auto_ptr<byte>     array(new byte[SIZE]); 
С>        // -
С>        byte*   p = array.get();
С>        // -
С>        for (size_t i = 0; i < SIZE; i++) {
С>            *p++ = static_cast<byte>(i % 0x78);
С>        }
С>    }

С>    std::cout << ":end" << std::endl;
С>    _getch();

С>    return 0;
С>}
С>


1. Выполните код:
std::cout << SIZE << std::endl;

Что выведет программа? Есть вероятность, что будет не 5368709120, а 1073741824 (из-за переполнения).

2. Деструктор std::auto_ptr делает «delete Pointer», но здесь нужен «delete[] Pointer».
Пётр Седов (ушёл с RSDN)
Re: Как выделить одному приложению 5 ГБ памяти?
От: Uzumaki Naruto Ниоткуда  
Дата: 02.01.08 18:19
Оценка:
Можно поинтересоваться? А зачем выделять столько памяти? Просто праздное любопытство...

А насчет сложностей — странно все это, вот люди выделяют:


Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Пётр Седов Россия  
Дата: 03.01.08 07:17
Оценка:
Здравствуйте, Uzumaki Naruto, Вы писали:
UN>А насчет сложностей — странно все это, вот люди выделяют:
В этом коде выделяется 5 блоков по 1 гб каждый. А как насчёт выделить один непрерывный блок размером 5 гб?
Пётр Седов (ушёл с RSDN)
Re: Как выделить одному приложению 5 ГБ памяти?
От: Пётр Седов Россия  
Дата: 03.01.08 08:17
Оценка:
Здравствуйте, Skipper_N, Вы писали:
S_N> Зачем нужны были эти все шаги? Все просто — 32-разрядное приложение не может адресовать более 4 гигабайта оперативной памяти (2 в степени 32 — даст около 4 млрд байт), а на деле — не более 3 гигабайт винда даст адресовать.
Вообще-то, Win32-программа может адресовать > 3 гб памяти. Начиная с Windows 2000 для этого есть address windowing extensions (AWE). Идея такая же, как в древних extended memory (XMS) и expanded memory (EMS): куски «большой» памяти по очереди (одновременно нельзя) проецируются в «маленькое» адресное пространство. Это делается с помощью WinAPI-шных функций:
AllocateUserPhysicalPages
MapUserPhysicalPages
MapUserPhysicalPagesScatter
FreeUserPhysicalPages
Помимо MSDN, они описаны в книге
Автор(ы): Джеффри Рихтер
Это издание — практически новая книга, посвещенная программированию серьезных приложений на Microsoft Visual C++ в операционных системах Windows 2000 (32- и 64-разрядных версиях) и Windows 98 с использованием функций Windows API. Состоит из 27 глав, двух приложений и предметного указателя. Гораздо глубже, чем в предыдущих изданиях рассматриваются такие темы, как взаимодействие с операционной системой библиотеки C/C++, программирование DLL и оптимизация кода, описываются новые механизмы и функции, появившиеся в Windows 2000, и приводится информация, специфическая для 64-разрядной Windows 2000. В этом издании автор, перейдя с языка C на C++, переработал все программы-примеры и представил ряд новых приложений, например ProcessInfo и LISWatch. Также появились совершенно новые материалы: выравнивание данных, привязка потоков к процессорам, кэш-линии процессоров, архитектура NUMA, перехват API-вызовов и др. Книга предназначена профессиональным программистам, владеющим языком C/C++ и имеющим опыт разработки Windows-приложений. Прилагаемый компакт-диск содержит все программы из книги (исходный код и исполняемые файлы для процессоров x86, IA-64 и Alpha).
Рихтера.
Пётр Седов (ушёл с RSDN)
Re[3]: Как выделить одному приложению 5 ГБ памяти?
От: Uzumaki Naruto Ниоткуда  
Дата: 03.01.08 20:12
Оценка: :)
5Гб за раз — это другой вопрос... =) Может я не понял проблему человека. Хотя мне до сих пор не понятно, зачем выделять столько памяти да и еще одним блоком? Он че ядерный взрыв моделирует?

Re[4]: Как выделить одному приложению 5 ГБ памяти?
От: Пётр Седов Россия  
Дата: 04.01.08 09:29
Оценка:
Здравствуйте, SergH, Вы писали:
SH>В виртуальном пространстве память резервируется страницами.
Точнее, VirtualAlloc(MEM_RESERVE) резервирует диапазон виртуальных адресов с округлением в 64 кб (= SYSTEM_INFO::dwAllocationGranularity). То есть начальный адрес и размер диапазона делятся на 64 кб без остатка. А вот VirtualAlloc(MEM_COMMIT) подкрепляет виртуальные адреса физическим хранилищем с округлением в SYSTEM_INFO::dwPageSize (обычно 4 кб). То есть страницами распределяется именно физическая память.
Пётр Седов (ушёл с RSDN)
4GB RAM на 32х битах - недостижимая цель?
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 08.01.08 12:32
Оценка: 3 (1)
Здравствуйте, Skipper_N, Вы писали:

S_N> Зачем нужны были эти все шаги? Все просто — 32-разрядное приложение не может адресовать более 4 гигабайта оперативной памяти (2 в степени 32 — даст около 4 млрд байт), а на деле — не более 3 гигабайт винда даст адресовать.

не совсем все так — короче вот более полное исследование по данному вопросу:
Четыре гигабайта памяти &mdash; недостижимая цель?
Более 4 Гб RAM и 32-битная Windows Vista

проблема же с 5 Гб как правильно в ветке уже заметили — скорее всего в неиспользовании правильного API ибо дефолтная реализация new или чем Вы там выделяли память в Вашем компиляторе, похоже, незаточена под Ваши требования. Так что я бы тоже рекомендовал почитать Рихтера и MSDN поновее (онлайн) про VirtualAlloc, причем на Висте и дальше я бы попробовал с флажком MEM_LARGE_PAGES.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Pavel Dvorkin Россия  
Дата: 10.01.08 11:43
Оценка: 6 (3)
Здравствуйте, Skipper_N, Вы писали:

Прочитал я все, что тут понаписали. Совет насчет VirtualAlloc могу только поддержать, но вот new намерен реабилитировать (частично

S_N> int* p = new int[1250000000];


S_N> 4. Делаем в тулбаре справа от написанного текста "Debug" — вместо "Win32" — "x64". (для этого в Configuration Manager, заходим в "Active Solution Platform", <New...>).


S_N> Теперь у нас 64-разрядное приложение, мы его компилируем и оно компилится.


И выдается при этом

warning C4307: '*' : integral constant overflow

как раз на эту строчку.

Заменяем на

__int64 size = 1250000000;
int* p = new int[size];

а для проверки

p[size — 1] = 0;


У меня на машине только 2Гб, поэтому new отрабатывал несколько минут, в течение которых был почти полностью заблокирован интерфейс пользователя, а иногда даже нажати на Caps Lock не приводило к включению лампочки и курсор мыши не передвигался . Но я набрался терпения и дождался, когда это кончится, после чего оператор проверки сработал без проблем.

S_N>Вот такое неожиданное открытие я сделал.


Предлагаю открытие это закрыть

>В книжках, о том, сколько максимум способен выделить один new (4 ГБ) — почему-то не пишут...


И правильно делают

>И пока у всех 32-разрядные платформы, никто этим не занимался. Но в будущем, возможно, когда будут 64-разрядные платформы, еще много кто сделает для себя такое открытие.


Надеюсь, не будут

Ну а что касается того, что new реабилитирован частично — не надо в куче такие блоки выделять.

int* p = (int*) VirtualAlloc(NULL, size * 4, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

сработало мгновенно. Реально при этом ничего не выделяется — зачем ? Будут обращения — тогда и будет выделяться.

Куча — вещь довольно сложная, не надо с ней так обращаться. Даже если на машине >4 Gb.
With best regards
Pavel Dvorkin
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Analytic2007 Россия https://www.viva64.com/ru/pvs-studio/
Дата: 17.02.08 06:57
Оценка:
Здравствуйте, SergH, Вы писали:

S_N>> Чтобы работало мое приложение (алгоритм) — нужно 5 ГБ памяти, меньше никак.


SH>Как память выделяешь? VirtualAlloc[Ex] попробуй.


Не смущайте народ.
Не стоит использовать такие тяжеловесные вещи, если хватит простого оператора new.
Все отлично выделяется и работает:
  size_t arraySize = 5368709120ULL;
  char *array = new char [arraySize];
  for (size_t i = 0; i != arraySize; ++i)
    array[i] = 1;
Re[2]: Как выделить одному приложению 5 ГБ памяти?
От: Analytic2007 Россия https://www.viva64.com/ru/pvs-studio/
Дата: 17.02.08 07:09
Оценка:
Здравствуйте, Стэн, Вы писали:

С>
С>#define SIZE    (5 * 1024 * 1024 * 1024)
С>...
С>std::auto_ptr<byte>     array(new byte[SIZE]); 
С>


Добро пожаловать в 64-битный мир.
По опыту скажу, что это самая распространенная ошибка переполнения при переходе на 64-битные системы. Более подробно о подобных ошибках можно почитать в разделе "14. Смешанное использование простых целочисленных типов и memsize-типов" в статье "20 ловушек переноса Си++ &mdash; кода на 64-битную платформу"
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.