Указатель на 400 000 000 элементов???
float *AA_=new float[nProjTotal*nProjTotal];
Говорит об ошибке!!! Оперативки 3 Гб.
Я думаю, что это связано с тем, что не хватает памяти, под указатель ... если ли тип "long указатель"??????
float *AA_=new float[nProjTotal*nProjTotal];
Говорит об ошибке!!! Оперативки 3 Гб.
Я думаю, что это связано с тем, что не хватает памяти, под указатель ... если ли тип "long указатель"??????[/QUOTE]
Боже мой, куда мир картится. Какой размер у float?? Ты пытаешься выделить больше чем три гига.
В таких задачах используют псевдо массивы - где память выделяется только под нужные элементы массива.
Мне все нужны!!!!
Не понятно при чем тут указатель и ошибка?
Сделай сначала sizeof(float) а потом sizeof(float[1000]) и сравни.
Да и вообще выделение памяти под Windows мало зависит от количества оперативки.
Используй псевдо массивы!!!!
Используй псевдо массивы!!!![/QUOTE]
У меня массив общего вида (в нем даже 0 нет).
Сделай сначала sizeof(float) а потом sizeof(float[1000]) и сравни.
[/QUOTE]
Да, вообще-то не сильно отличается....
Вот примерное объявление класса мегамассива.
{
private:[INDENT]bool _fChanged; // Флаг наличия изменения текущей страницы
float *_fPage; // Указатель на текущую страницу массива в ОЗУ
int _fSize; // Размер страницы файла подкачки (в байтах или элементах
__int64 _fCurrent; // Номер текущей страницы
_int64 _fCount; // размер массива (64-х разрядное число :D )
AnsiString _fFile_Name; Имя файла подкачки
int _fFile; // Объект открытого файла подкачки
bool Find_Page (__int64 MegaIndex, __int64 &PageNumber, int &PageIndex); // Определение номера страницы и элемента страницы для указанного элемента массива
void Swap_Pages (__int64 New_Page); // Запись текущей страницы и чтение другой
[/INDENT]
public:[INDENT]float& operator[] (__int64 Index); // Изменяемая операция индексации
float operator[] (__int64 Index) const; // Константная операция индексации
[/INDENT]};
Конкретную реализацию чтения/записи в файл попробуйте придумать сами ;)
Для большей оптимальности программы можно вместо одной страницы использовать несколько страниц - список, в котором при загрузке новой страницы будет сбрасываться страница, к которой не обращались дольше всех. Это сделать сложнее - но дерзайте
Дальше покопай в сторону HeapCreate и VirtualAlloc .
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/address_windowing_extensions.asp[/QUOTE]
Бесполезно - больше определённого предела система выделить не сможет никак. Только "ручками", с собственным алгоритмом работы с жёстким диском.
В винде - это 2 ГБ, при наличии определенного ключа 3гб. Почему думаю объяснять не надо?
Это я к тому, что если программа требует 3 ГБ ОЗУ, то она точно также может требовать и 5 ГБ :D. Так что лучше сразу писать свой код свопирования, не зависимый от настроек ОС :)
float *AA_=new float[nProjTotal*nProjTotal];
Говорит об ошибке!!! Оперативки 3 Гб.
Я думаю, что это связано с тем, что не хватает памяти, под указатель ... если ли тип "long указатель"??????[/QUOTE]
а не проще ли хранить эти данные в файле и написать класс возращающий необходимое значение из него при необходимости ?
class Data
{
public:
float Get( unsigned int number ); // в этой функции осуществляеться выборка из файла.
};
Это я к тому, что если программа требует 3 ГБ ОЗУ, то она точно также может требовать и 5 ГБ :D. Так что лучше сразу писать свой код свопирования, не зависимый от настроек ОС :)[/QUOTE]
Есть просто вычислительные задачи, где требуется оперативный доступ ко всей информации, так как быстродействие при обращении к данным - критический параметр. А размерность данных строго известно заранее. Тогда почему бы и нет? А если требуется больше - имеет смысл соответствующее железо. 64-битный процессор и памяти по максимому и вперед.
"Здравствуйте, я ваша тётя" :)
Я почти неделю тому назад полное решение привёл - объект, который для внешне выглядит как массив. Осталось только реализацию файлового ввода/вывода дописать.
"Здравствуйте, я ваша тётя" :)
Я почти неделю тому назад полное решение привёл - объект, который для внешне выглядит как массив. Осталось только реализацию файлового ввода/вывода дописать.[/QUOTE]
гыг... писать свой алгоритм подкачки ? не смеши меня.... если немного пораскинутьь мозгами то можно задействовать механизм винды....
ну например.... допустим мы можем получить размер свободной памяти 1гб, а нам требуется 3 гб, делаем три файла по 1гб, и по необходимости проецируем их по одному на выделенную память.... идея конечно нуждается в доработке....
Ты ссылку вообще прочитал? Цитирую первую же строчку:
[QUOTE=msdn]
Address Windowing Extensions (AWE) is a set of extensions that allows an application to quickly manipulate physical memory greater than 4GB.[/quote]
Выделяется теоретически произвольное количество памяти. Просто в каждый момент времени доступно максимум 4 Гб (вычти потребление памяти ядром ОС). Фишка работает по принципу оконного отображения. Переключать окна, правда, придется программисту. Реализуй алгоритм переключения - вот, собсно, и более простая и более "естественная" для винды замена твоему "алгоритму подкачки".
У AWE есть ограничения, и если AWE чем-то не нравится - используй отображение файла в память
Ага, только где будут физически храниться "активные" данные: в ОЗУ или в файле? В последнем случае, читать/писать каждый элемент отдельно будет несколько.... накладно :confused:
Да, знаю, "кэширование" и всё такое... Но кэш - вешь такая, что используется многими программами сразу. А тут лежит себе эта "страница" в ОЗУ, никого не трогает :) - читаешь её, пишешь, а как в другой надобность возникла - сохранил и считал новую.
И вообще, когда "ручками" что-то делаешь - начинаешь понимать что к чему.:D
А если лезть в механизм управления памяти Windows, то где гарантия, что с вашей программой, по какой-то понятной им одним причинам, перестанут дружить другие программы :(
Дальше покопай в сторону HeapCreate и VirtualAlloc .[/QUOTE]
Копал... ничего не получилось...
class Data
{
public:
float Get( unsigned int number ); // в этой функции осуществляеться выборка из файла.
};[/QUOTE]
Долго
Долго :) - а как надо, быстро, дёшево и сердито? Так сердиться то ось будет - на Вас и Вашу программу :D
В общем, код объявления мегамассива я привёл - дерзайте с реализацией. И вообще, объекты - штука такая, их долго разрабатывать, зато быстро использовать.
Или "долго" программа работает - оптимизируйте.
в виртуальном адресном пространстве процесса.... сча погуляю с собачкой приду и напишу код.... задача интересная.... ща...
//
#include "stdafx.h"
#include <windows.h>
using namespace std;
#define MAX_FILE_SIZE 0x3fffffff
template<typename T>
class Data
{
public:
Data( __int32 max_size )
{
__int64 data_size = sizeof(T) * max_size;
int num_of_files = (int)( data_size / MAX_FILE_SIZE ) + 1;
memory = (T*)(new char[MAX_FILE_SIZE]);
strcpy( filename, "e:\\data0.dat" );
for( int i = 0; i < num_of_files; i++ )
{
char str_numfile[5];
filename[8] = *(itoa( i, str_numfile, 10 ));
hFile = CreateFile( filename, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
hMapFile = CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0, MAX_FILE_SIZE, NULL );
}
DWORD ErrCode = GetLastError();
/*SetFilePointer( hFile, (max_size*sizeof(T)), 0, FILE_BEGIN );
DWORD NumberOfBytesWriten;
char buffer = 'a';
WriteFile( hFile, &buffer, sizeof(buffer), &NumberOfBytesWriten, NULL );*/
}
~Data()
{
//CloseHandle( hFile );
}
void SetValue( T value, __int64 position )
{
int num_file = ( position / MAX_FILE_SIZE ) + 1;
if ( num_file != curr_file )
{
MapViewOfFileEx( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0, memory );
curr_file = num_file;
}
__int32 pos_in_map = (position - ( (num_file-1) * MAX_FILE_SIZE )) / sizeof(T);
memory[pos_in_map] = value;
}
T GetValue( __int32 position )
{
int num_file = ( position / MAX_FILE_SIZE ) + 1;
if ( num_file != curr_file )
{
MapViewOfFileEx( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0, memory );
curr_file = num_file;
}
__int32 pos_in_map = (position - ( (num_file-1) * MAX_FILE_SIZE )) / sizeof(T);
T value = memory[pos_in_map];
return value;
}
protected:
int curr_file;
HANDLE hFile[9];
HANDLE hMapFile[9];
char filename[20];
T* memory;
};
int _tmain(int argc, _TCHAR* argv[])
{
Data<int> data( 700000000 );
cout << "start set data" << endl;
for( int i = 0; i < 700000000; i+=1000 )
{
data.SetValue( i+1, i );
}
int pause;
/*cout << "press key to start get data " << endl;
cin >> pause;*/
for( int i = 0; i < 20000; i+=1000 )
{
cout << data.GetValue( i ) << endl;
}
cin >> pause;
for( int i = 699999000; i > 500000000; i-=1000 )
{
cout << data.GetValue( i ) << endl;
}
cin >> pause;
return 0;
}
вообщем у меня все неплохо фунциклирует.... при том что у меня 768mb оперативки... а работает с 1гб
А какая процессу разница, сколько на ПК физической памяти - на 256 МБ всё работало бы точно также - только медленнее? Программа всё равно работает с виртуализованной памятью, переадресацией которой занимается CPU.
И почему GetValue использует int32, а SetValue - int64?
И зачем вообще эти функции - для массива нужно переопределить оператор [].
Особенно поразили такие вещи:
1. Ты запутал сам себя с тусованием типов int, __int32 и __int64.
2. Некрасиво
нагляднее писать
3. Нелепо писать
тем более при
4. Забавная нелепость
filename[8] = *(itoa( i, str_numfile, 10 ));
почему 5, а потом берем только первую цифру?
Это потенциальный баг, например при количестве файлов больше 10.
Кроме того, это опять же какое-то нелепое конструирование имени файла в C-стиле, когда есть полноценный C++.
Кстати, а что делать, если у меня нет диска E: ? :D
5. Это зачем?
6. Файлы никогда не закрываются, память не освобождается, Unmap не вызывается?
7. Странно, размер контейнера задается в элементах
{
__int64 data_size = sizeof(T) * max_size;
а выборка элемента происходит по байтовой позиции
{
int num_file = ( position / MAX_FILE_SIZE ) + 1;
<skip>
__int32 pos_in_map = (position - ( (num_file-1) * MAX_FILE_SIZE )) / sizeof(T);
Это явный баг!
8. А для чего char filename[20]; является полем класса?
9. А почему бы это не оформить в виде обычного контейнера?
10. Внизу это у тебя "пример использовани" или unitest-ы ? :)
P.S. Насчет трояна : у меня на компе информация соствавляющая государсвенную тайну. можт сам раскажешь что успел нарыть или мне куратору из СБУ позвонить ? ты ж не хочешь что б наш разговор перешел в реал ?
[/QUOTE]
На счет идеи... идея не плохая, но мне кажется для начала все же надо выяснить, для чего понадобилось столько памяти. Вполне возможно, что просто неправильно поставлена задача изначально.
Что же касается реализации, то код твой в корне неверный.
Например, для чего создавать массив memory? Чтобы добить свопфайл? :)
Кроме того раз уж ты его создаешь, то надо обеспечить выравнивание на 64K.
Еще один баг: ты не инициализируешь поле curr_file.
Человек, который сможет довести этот сырой код до ума, сможет написать его сам и с нуля. Для чего же тогда его (код) приводить? Чтобы запутать противника? :)
[QUOTE=PitxBull]
P.S. Насчет трояна : у меня на компе информация соствавляющая государсвенную тайну. можт сам раскажешь что успел нарыть или мне куратору из СБУ позвонить ? ты ж не хочешь что б наш разговор перешел в реал ?
[/QUOTE]
По поводу трояна, это ты ко мне обращаешься?
У тебя параноя...
Насмешил... :D
Государственную тайну? Это про роботов с ИИ управляющие ракетами?
Ой! Я не расскрыл твою гос. тайну? :D
Я просто жаждю разговора в реале вместе с куратором или узурпатором или как там его...
//
#include "stdafx.h"
#include <windows.h>
using namespace std;
#define MAX_FILE_SIZE 0x3fffffff
template<typename T>
class Data
{
public:
Data( __int32 max_size )
{
__int64 data_size = sizeof(T) * max_size;
int num_of_files = (int)( data_size / MAX_FILE_SIZE ) + 1;
//memory = (T*)(new char[MAX_FILE_SIZE]);
strcpy( filename, "f:\\data0.dat" );
for( int i = 0; i < num_of_files; i++ )
{
char str_numfile[5];
filename[8] = *(itoa( i, str_numfile, 10 ));
hFile = CreateFile( filename, GENERIC_READ | GENERIC_WRITE, 0,
NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
hMapFile = CreateFileMapping( hFile, NULL, PAGE_READWRITE, 0, MAX_FILE_SIZE, NULL );
DWORD ErrCode = GetLastError();
}
curr_file = 1000;
/*SetFilePointer( hFile, (max_size*sizeof(T)), 0, FILE_BEGIN );
DWORD NumberOfBytesWriten;
char buffer = 'a';
WriteFile( hFile, &buffer, sizeof(buffer), &NumberOfBytesWriten, NULL );*/
}
~Data()
{
//CloseHandle( hFile );
}
void SetValue( T value, __int64 position )
{
unsigned __int64 byte_position = position * sizeof(T);
int num_file = ( byte_position / MAX_FILE_SIZE );
if ( num_file != curr_file )
{
UnmapViewOfFile( memory );
memory = NULL;
memory = (T*)MapViewOfFile( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0 );
//LPVOID res = MapViewOfFileEx( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0, memory );
DWORD ErrCode = GetLastError();
curr_file = num_file;
}
unsigned __int32 pos_in_map = (byte_position - ( num_file * MAX_FILE_SIZE )) / sizeof(T);
memory[pos_in_map] = value;
}
T GetValue( __int64 position )
{
unsigned __int64 byte_position = position * sizeof(T);
int num_file = ( byte_position / MAX_FILE_SIZE );
if ( num_file != curr_file )
{
UnmapViewOfFile( memory );
memory = NULL;
memory = (T*)MapViewOfFile( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0 );
//LPVOID res = MapViewOfFileEx( hMapFile[num_file], FILE_MAP_WRITE, 0, 0, 0, memory );
DWORD ErrCode = GetLastError();
curr_file = num_file;
}
unsigned __int32 pos_in_map = (byte_position - ( num_file * MAX_FILE_SIZE )) / sizeof(T);
T value = memory[pos_in_map];
return value;
}
protected:
int curr_file;
HANDLE hFile[9];
HANDLE hMapFile[9];
char filename[20];
T* memory;
};
int _tmain(int argc, _TCHAR* argv[])
{
Data<int> data( 700000000 );
cout << "start set data" << endl;
for( int i = 0; i < 700000000; i++ )
{
data.SetValue( i+1, i );
}
int pause;
/*cout << "press key to start get data " << endl;
cin >> pause;*/
for( int i = 0; i < 20000; i+=1000 )
{
cout << data.GetValue( i ) << endl;
}
cin >> pause;
for( int i = 700000000 - 1000 ; i > 500000000; i-=1000 )
{
cout << data.GetValue( i ) << endl;
}
cin >> pause;
return 0;
}
да!!! но не ты, не el scorpio, ни великий преподователь aks до этого не додумались. а додумался я , PitxBull.
[QUOTE=Green]
но мне кажется для начала все же надо выяснить, для чего понадобилось столько памяти. Вполне возможно, что просто неправильно поставлена задача изначально.
[/QUOTE]
сразу видно - электрик. ты видишь все с точки зрения разработки игр и других попсовых систем. в совремменных наукоемких приложениях такие запросы памяти обычное дело.
[QUOTE=Green]
Что же касается реализации, то код твой в корне неверный.
Например, для чего создавать массив memory? Чтобы добить свопфайл? :)
Кроме того раз уж ты его создаешь, то надо обеспечить выравнивание на 64K.
[/QUOTE]
да вообщем то я хотел один раз выделить себе памяти и больше с этим не возиться. а тут еще это выравние.... какой садист писал эту винду ? ужасть... 15 минут на ровном месте..
[QUOTE=Green]
Еще один баг: ты не инициализируешь поле curr_file.
[/QUOTE]
просто были задачи поинтереснее.
[QUOTE=Green]
Человек, который сможет довести этот сырой код до ума, сможет написать его сам и с нуля. Для чего же тогда его (код) приводить? Чтобы запутать противника? :)
[/QUOTE]
ну и кто тут написал его с нуля ? кроме меня конечно.
А лучше - контейнер типа String (CString, AnsiString - в зависимости от языка)
T GetValue( __int64 position ) - очередной глюк. T - может быть структурой с пару сотен байт размером - всё через стек передавать накладно до невозможности. Нужно использовать ссылки - константную и изменяемую.
T value = memory[pos_in_map] - опять же, ссылка напрашивается сама собой.
По прежнему большая путаница в целочисленных типах.
Что же касается внутренней реализации - нечитабельно. Без бутылочки не разберёсси :D
[/quote]
Не надо себя так громко бить пяткой в грудь. Во-первых, это неприятно; во-вторых, это неудобно; в-третьих, объявление класса я написал ещё на первой странице темы :D
Так, играми и прочей "попсой" мы, значит, уже не увлекаемся ;)
А в "наукоёмких" приложениях используются либо базы данных, которые избавляют от таких требований к ОЗУ, либо специализированные ЭВМ, не совместимые с обычными "писюками", и проблемы подобные там решаются по-другому.
Билл Гейст - Великий у Ужасный. Другой вопрос - Чем?
Я пишу. В свободное время личного интереса ради.
Реализация почти готова - объекты многоуровневые, потому и сложные.
Функций много - зато все простые, интуитивно понятные, и большей частью - встроенные, потому и быстрые.
Алгоритм подкачки расчитан на поддержку нескольких страниц для оптимизации операций ввода/вывода при обращении к разным диапазонам.
Как допишу и отлажу - выложу.
А лучше - контейнер типа String (CString, AnsiString - в зависимости от языка)
[/QUOTE]
Блин, язык то в конце концов один. И строковый тип стандартный есть для него ) Любите вы нестандартными вещами пользоваться даже там где этого не требуется.
Отсюда и стандартные (для данной реализации языка) строковые контейнеры.
Тем более, постоянно придётся писать код для проверки длины имени файла.
[/QUOTE]
Чтож к замечаниям ты прислушиваешься, значит, не все потерянно. Жаль, что не ко всем...
Твой код остается неработоспособным на граничных условиях. Это легко выявляется юнит-тестами. Рекомендую освоить.
Кроме того теперь твой код просто захламлен старым заремаренным кодом. Совет: освой системы контроля версий, не будешь разводить помойку в коде.
Теперь о вновь замечанных багах и странных местах в коде:
1) почему curr_file = 1000; а не 3000 ? :)
2) HANDLE hFile[9]; почему 9? И где тогда проверяется это ограничение?
3) char filename[20]; почему 20?
T GetValue( __int64 position ) - очередной глюк. T - может быть структурой с пару сотен байт размером - всё через стек передавать накладно до невозможности. Нужно использовать ссылки - константную и изменяемую.
[/QUOTE]
Ссылка здесь может быть невалидной, т.к. она будет указывать в одно место памяти, а содержимое этой области будут в разный момент времени занимать разные файлы.
Но не думаю, что PitxBull исходил из этих соображений, т.к. в SetValue как раз нужно применить именно константную ссылку. :)
ask имеет в виду std::string.
[/QUOTE]
Согласен, при использовании результатов-ссылок для следующий код окажется неработспособным при использовании одной страницы.
const TMyStruct &Item2 = MegaArray.GetValue (1000000);
Но если писать объект, изначально ориентируясь на многостраничный обмен данными, то всё будет куда безопаснее. Хотя и сложнее.
Пусть мы укажем объекту использовать 16 страниц - наврядли кто-либо станет использовать одновременно столько ссылок на элементы массива, тем более, в разных его частях.
Пусть мы укажем объекту использовать 16 страниц - наврядли кто-либо станет использовать одновременно столько ссылок на элементы массива, тем более, в разных его частях.[/QUOTE]
Собственно, когда я говорил, что для начала надо выяснить, для чего столько памяти, я и имел в виду, что всё зависит от конкретной задачи и врядли кому-то одновременно потребуется столько памяти. Поэтому задачу, как мне кажется надо решать с другого конца - лечить причину, а не симптомы. Проблема не в недостатке памяти, а в неправильном видении проблемы.
P.S. 16 страниц невозможно, автор жестко прошил (в нескольких местах) не более 9. :D
[QUOTE=Green]P.S. 16 страниц невозможно, автор жестко прошил (в нескольких местах) не более 9. :D[/QUOTE]
А это ещё с какого перепугу :confused: ?
Пока мой объект имеет пару открытых свойств: кол-во элементов, и кол-во выделяемых страниц. Над первым я ещё подумаю, а второе можно изменять динамически, исходя из текущих условий работы объекта.
Ну и конечно же две реализации operator [] (int Index). 2147483647 - два миллиарда элементов хватит за глаза любой задачи - в противном случае ей на IBM PC просто не место :D