Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.07.2020, 01:39   #1
ccccfr
Пользователь
 
Регистрация: 26.02.2011
Сообщений: 12
По умолчанию Как эффективнее обрабатывать большой файл по кускам?

Есть файл во много раз больший оперативной памяти. Собираюсь реализовать алгоритм, который загружает часть файла, помещающуюся в оперативную память и там обрабатывает. Как сделать это с максимальной эффективностью по времени на C++ под Windows? Mapping файла на оперативную память? Если так. То как определить размер куска, который поместится в оперативную память?

Последний раз редактировалось ccccfr; 14.07.2020 в 07:23.
ccccfr вне форума Ответить с цитированием
Старый 14.07.2020, 12:25   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Читайте файл кусками, кратными 256К и без буферизации (FILE_FLAG_NO_BUFFERING) и в память, которая закреплена в памяти (не подкачивается).
waleri вне форума Ответить с цитированием
Старый 15.07.2020, 17:45   #3
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от ccccfr Посмотреть сообщение
То как определить размер куска, который поместится в оперативную память?
В любом случае - грузить частями, и лучше создать для них несколько отдельных потоков Thread. Причём кол-во тредов не должно превышать кол-во ядер у процессора, х2. Иначе, если у проца например 4-ядра, а приложение будет 10-12 поточное, то весь профит уйдёт на переключение этих потоков.

Mapping файла не имеет смысла, если между частями не нужна синхронизация, т.е. они не должны обмениваться данными. В общем случае я бы сделал такой алго:

1. GetProcessAffinityMask() - получили кол-во ядер CPU.
2. Умножить пункт 1 на 2..
3. CreateThread() - создать кол-во потоков по результату пункта 2.
4. GetFileSizeEx() - узнать размер файла.
5. Разделить размер файла на кол-во тредов из пункта 3.
6. В каждом потоке Thread выставить указатель на чтение SetFilePointerEx() кратное пункту 5.
7. Все потоки обрабатывают свою часть данных.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 24.07.2020, 15:52   #4
Android1
Форумчанин
 
Регистрация: 26.08.2010
Сообщений: 121
По умолчанию

Цитата:
Сообщение от R71MT Посмотреть сообщение
В любом случае - грузить частями, и лучше создать для них несколько отдельных потоков Thread. Причём кол-во тредов не должно превышать кол-во ядер у процессора, х2. Иначе, если у проца например 4-ядра, а приложение будет 10-12 поточное, то весь профит уйдёт на переключение этих потоков.
А разве можно с жетского диска читать в более, чем один поток ? Считывающая головка HDD ведь одна, как она будет на многопоточность работать ?
Android1 вне форума Ответить с цитированием
Старый 24.07.2020, 20:27   #5
R71MT
Участник клуба
 
Аватар для R71MT
 
Регистрация: 16.06.2011
Сообщений: 1,428
По умолчанию

Цитата:
Сообщение от Android1 Посмотреть сообщение
А разве можно с жетского диска читать в более, чем один поток ?
а почему нельзя?
пункт 6 как раз и делит файл на потоки.
Нашедшего выход - затаптывают первым..
R71MT вне форума Ответить с цитированием
Старый 24.07.2020, 21:22   #6
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от Android1 Посмотреть сообщение
А разве можно с жетского диска читать в более, чем один поток ? Считывающая головка HDD ведь одна, как она будет на многопоточность работать ?
Головок там N-штук от 4 до 16. Так пока диск вращается под головкой пробегает куча секторов. В теории диск может поместить в кэшировать целый цилиндр. А далее жеский диск распиивает данные в ОЗУ по нескольким буферам(потоков).
На практике такое делать не стали хотя технология и проработана и вроде как в SAS дисках использовалась.

Цитата:
Сообщение от R71MT Посмотреть сообщение
а почему нельзя?
Можно, будет медленнее чем однопоточное чтение. Так как головка будет постоянно перепозироваться.

Цитата:
1. GetProcessAffinityMask() - получили кол-во ядер CPU.
Устаревшая функция если у вас больше 64 ядер то не заработает.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как в Eclipse протестировать код по кускам RAFA91 Общие вопросы по Java, Java SE, Kotlin 5 15.05.2016 14:47
Большой файл с функциями Jleksern PHP 7 12.12.2014 12:19
Большой текстовый файл D_E_N Общие вопросы Delphi 48 21.11.2013 20:26
Не заливается на ФТП большой файл ramzes777 Работа с сетью в Delphi 3 26.10.2011 10:19
отдавать большой файл с фтп TaTT DoGG PHP 5 03.07.2009 10:34