Как лучше организовать файл кэша пользовательских индикаторов? - страница 2

 
Sergey Savinkin:

Советник может быть тот же, отдельная оптимизация не нужна.

Если кэша нет — считаем и записываем. Если есть — читаем и используем.

 

Вставлю свои 5 копеек. 

Просто мысль вслух:
Было бы разумным задуматься о не использовании типа double для хранения буферов индикаторов, т.к. этот тип очень избыточен - 8 байт. В большинстве случаев разницу в пипсах между двумя соседними значениями буфера можно запихнуть в 1 байт, даже 5 бит.
Самый правильным считаю использование массива uchar с использованием битовых масок (думаю 3 бита будет достаточно: 1бит-знак, 2бита - сколько последующих байт хранят текущее значение ) 

По сути это будет просто более компактный формат хранения буферов.
И больше это даже нужно не для уменьшения размеров файла и времени их записи и считывании.
Главная задача - чтобы суммарный объем сидящих в теле программы массивов не превышал внутреннего кэша процессора. Это обеспечивает более шуструю работу.
На глазок выигрыш в объеме использования памяти будет минимум в 4 раза. И шансы переполнения кэша процессора резко падают.

Если суммарный объем массивов типа double не превышает размера кэша процессора, тогда, пожалуй, не стоит с этим заморачиваться. 

Да, это весьма объемная задача.

Нужна будет особая организация процессов компрессии и декомпрессии данных "на лету".
Но это все решаемо при желании.

ЗЫ
Вообще странно почему MQ использует в своих буферах такой прожорливый тип double.
Хотя как знать - может это только видимость, а в реальности в реализации функции CopyBuffer приходит приблизительно по такому сценарию компрессии-декомпрессии.
Хотя это вряд ли судя по скорости выполнения CopyBuffer...

 
Nikolai Semko:

Вставлю свои 5 копеек. 

Просто мысль вслух:
Было бы разумным задуматься о не использовании типа double для хранения буферов индикаторов, т.к. этот тип очень избыточен - 8 байт. В большинстве случаев разницу в пипсах между двумя соседними значениями буфера можно запихнуть в 1 байт, даже 5 бит.
Самый правильным считаю использование массива uchar с использованием битовых масок (думаю 3 бита будет достаточно: 1бит-знак, 2бита - сколько последующих байт хранят текущее значение ) 

По сути это будет просто более компактный формат хранения буферов.
И больше это даже нужно не для уменьшения размеров файла и времени их записи и считывании.
Главная задача - чтобы суммарный объем сидящих в теле программы массивов не превышал внутреннего кэша процессора. Это обеспечивает более шуструю работу.
На глазок выигрыш в объеме использования памяти будет минимум в 4 раза. И шансы переполнения кэша процессора резко падают.

Если суммарный объем массивов типа double не превышает размера кэша процессора, тогда, пожалуй, не стоит с этим заморачиваться. 

Да, это весьма объемная задача.

Нужна будет особая организация процессов компрессии и декомпрессии данных "на лету".
Но это все решаемо при желании.

ЗЫ
Вообще странно почему MQ использует в своих буферах такой прожорливый тип double.
Хотя как знать - может это только видимость, а в реальности в реализации функции CopyBuffer приходит приблизительно по такому сценарию компрессии-декомпрессии.
Хотя это вряд ли судя по скорости выполнения CopyBuffer...

Потому что исходное значение цены например 1.35862, по простому, если вынести точку за "2" -> 135862 - это уже int (4 байта) плюс для после точки надо что то для точности. Т.к. значения цен не лежат в узком диапазоне, вот и выходит double. Посещала мысль, все в int/float переделывать - выгода как от навара с яиц, т.е. в среде mql смысла не имеет. Кэш процессора постоянно "переполняется/заполняется", достоверно прогнозировать что именно в этот момент будет происходить расчет в кэше не возможно, но по getmicrosecondcount можно обнаружить что иногда расчет идет повторно по данным из кэша. А что, написать спо, чтобы загружалось и работало только в кэше, у xeon кэша много. Правда все равно памяти придется поставить наверно самое меньшее 16Гбайт - меньше не делают. Так то 32 Мбайт озу наверно за глаза для экспертов, надо интелу коллективное письмо написать - дай нам систему чтобы только с кэшем работала)))

 
Unicornis:

Потому что исходное значение цены например 1.35862, по простому, если вынести точку за "2" -> 135862 - это уже int (4 байта) плюс для после точки надо что то для точности. Т.к. значения цен не лежат в узком диапазоне, вот и выходит double. 

Я же писал

В большинстве случаев разницу в пипсах между двумя соседними значениями буфера можно запихнуть в 1 байт, даже 5 бит.
Самый правильным считаю использование массива uchar с использованием битовых масок (думаю 3 бита будет достаточно: 1бит-знак, 2бита - сколько последующих байт хранят текущее значение ) 

Это означает, что передавать нужно только первое значение и минимальное изменение значения, а дальше только разницу с предыдущим.
т.е., например,  если пипс = 0.00001, предыдущее значение 1.35862, а текущее 1.35837, то для передачи текущего значения достаточно передать (1.35837-1.35862)/0.00001= -25.

 
Nikolai Semko:

Хотя как знать - может это только видимость, а в реальности в реализации функции CopyBuffer приходит приблизительно по такому сценарию компрессии-декомпрессии.

Увы.
Судя по размеру файлов истории hcc хранится все в неупакованном виде. Очень жаль. 
Мне кажется это неразумным. Хранить историю минутных баров за год можно было бы в файле не в 16 Mb, а где-то в 2.5 Мб. Время компрессии и декомпрессии такого объема занимало бы по предварительным расчетам не более 10-20 миллисекунд, что гораздо быстрее, чем скорость записи и чтения дополнительных 13 Мб с HDD, и даже в несколько раз быстрее чем с SDD.


 
Nikolai Semko:

Я же писал

Это означает, что передавать нужно только первое значение и минимальное изменение значения, а дальше только разницу с предыдущим.
т.е., например,  если пипс = 0.00001, предыдущее значение 1.35862, а текущее 1.35837, то для передачи текущего значения достаточно передать (1.35837-1.35862)/0.00001= -25.

В таком случае нужно полное начальное значение, а потом высчитывать текущее значение путём поочерёдного прибавления сохранённых данных? На мой взгляд это не совсем рационально.

 
Сергей Таболин:

В таком случае нужно полное начальное значение, а потом высчитывать текущее значение путём поочерёдного прибавления сохранённых данных? На мой взгляд это не совсем рационально.

В чем нерациональность? Можете пояснить? 
Это будет осуществляться быстрее и при этом требует в разы меньше дискового пространства. 
По моему это как раз рационально.
Может Вы думаете,  что эти математические телодвижения ресурсоемки? Но это менее ресурсоемко, чем запись в файл
Вы знаете, что такие мат. операции как сложение, вычитание, умножение,  деление и даже квадратный корень выполняются меньше наносекунды в программе ex5?
Тогда как время, требующееся на запись или чтение в файл в потоке одного числа double(8 байт) это около 30  нс для SSD диска и в десятки раз больше для HDD.
Причина обращения: