У меня есть программа на C ++, задачей которой является анализ потока двоичных данных (обычно это файл на диске) и извлечение некоторой информации. Эта задача «без памяти», что означает, что результат каждого шага не зависит от предыдущего. Из-за этого я подумал ускорить его, передав данные отдельным потокам для повышения производительности.
Пока что данные читаются в блоках по 1 ГБ за раз и сохраняются в массиве, чтобы избежать узких мест ввода / вывода. Стоит ли разделять данные в n
чанках / массивах (где n
- количество потоков) или единый массив, к которому обращаются несколько потоков, не является проблемой?
У меня есть программа на C ++, задачей которой является анализ потока двоичных данных (обычно это файл на диске) и извлечение некоторой информации. Эта задача «без памяти», что означает, что результат каждого шага не зависит от предыдущего. Из-за этого я решил ускорить его, передав данные отдельным потокам для повышения производительности.
Пока что данные читаются в блоках по 1 ГБ за раз и сохраняются в массиве, чтобы избежать узких мест ввода / вывода. Стоит ли разделять данные в n
чанках / массивах (где n
- количество потоков) или единый массив, к которому обращаются несколько потоков, не является проблемой?
РЕДАКТИРОВАТЬ 1: данные и спецификации анализа
Я понимаю, что формулировка проблемы может быть слишком широкой, как указано в одном из комментариев. Я попытаюсь углубиться в детали.
Анализируемые данные представляют собой серию 64-разрядных целых чисел без знака, сгенерированных так называемым «цифровым преобразователем времени» (TDC), в котором хранится информация о метке времени для некоторого события, которое они регистрируют. Мой TDC имеет несколько каналов, поэтому каждая временная метка содержит информацию о том, какой канал сработал (первые 3 бита), был ли это триггер с нарастающим или падающим фронтом (4-й бит), и фактическое время (в тактах с момента включения TDC, последнее 60 бит).
Отметки времени, конечно же, сохраняются в файле в хронологическом порядке. Задача - найти совпадения событий между каналами в пределах определенного временного окна, которое устанавливает пользователь. Таким образом, вы продолжаете читать временные метки, и когда вы обнаруживаете два в интересующих каналах, чье расстояние во времени меньше установленного, вы увеличиваете количество событий совпадений.
Эти файлы могут быть довольно большими (десятки ГБ), а количество временных меток может быть огромным (один такт - 80 пико секунд).
Пока я только один раз просматриваю весь файл, и идея состояла в том, чтобы «разрезать» его на более мелкие части, которые затем будут анализироваться различными потоками. Возможная потеря событий между разрезами является приемлемой для меня, так как, самое большее, будет 2 на сотни тысяч.
Конечно, они будут читать только данные из файла / памяти. Я могу записать счетчики совпадений в трех отдельных переменных, а затем суммировать их по окончании всех потоков, если это помогает избежать проблем с синхронизацией.
Надеюсь, теперь все стало яснее.