У меня есть N элементов, которые нужно сравнить между собой, чтобы создать график. Это дает (N * N-1) / 2 Всего сравнений.
я бы хотел многопоточность этих сравнений У меня также есть несколько ограничений:
Каждый элемент довольно большой, на самом деле это матрица, поэтому копирование всех элементов в каждом потоке заняло бы слишком много памяти.
Каждое сравнение должно происходить, то есть я не могу его пропустить.
Каждый раз, когда новый элемент может быть добавлен в список, это очень сложно, потому что мне нужно отслеживать, что было сделано, чтобы сделать только новые.
Поскольку количество сравнений может быть огромным, например, 20 миллионов, у меня не может быть такой большой очереди.
Наконец, можно остановить процесс в любое время, я должен быть в состоянии возобновить работу с того места, где я находился, даже в другом исполнении приложения.
Пока у меня есть главный поток, который содержит все элементы и несколько рабочих в пуле потоков. Рабочие потоки сравнивают список пар или диапазон элементов. У меня есть мысль о генераторе сравнения, который дает следующие X сравнений по требованию.
Как я мог построить этот генератор?
Должен ли я копировать каждую пару для рабочих, использовать ReadWriteLock непосредственно с рабочего для чтения данных из Master?
Как я могу отслеживать прогресс в каждой теме?
Как я мог остановить и возобновить состояние сравнений?
Прошу прощения, если это много вопросов.
Спасибо !
Предполагая, что чтение является поточно-ориентированным (обычно это так долго, как никто не пишет), простое решение состоит в том, чтобы каким-то образом разделить задачи между набором рабочих потоков, делая это заранее. Например, для N рабочие, вы могли бы выделить пару (Икс, Y) к работнику Икс модификация N. Единственное сообщение позволяет каждому работнику знать его порядковый номер (0…N-1). Каждый поток должен отбросить свои ответы в приватный массив, который можно сопоставить после завершения всех остальных.
Более сложная модель, учитывающая различную производительность труда, состоит в том, чтобы выдвигать каждое значение на 0…N-1 в очередь. Каждый рабочий поток тянет число, Икс, вне очереди, оценивает каждый (Икс, Y), а затем возвращается за другим Икс.
Если вы хотите потратить время, более эффективно ставить пары в очередь, чтобы минимизировать перегрузку кеша. Это сложная проблема. По сути, вы хотите поставить в очередь пары из небольших кластеров элементов, чтобы каждая пара в кластере оценивалась примерно в одно и то же время. Как бы это ни было сложно, это может иметь огромное значение для эффективности вашего алгоритма.
Других решений пока нет …