Разделение файла с помощью целочисленной математики - PullRequest
2 голосов
/ 14 февраля 2011

Я читаю файл с n серверов, и я хочу, чтобы каждый загружал 1 / nth файла. Я думал, что какая-то быстрая целочисленная математика сработает, но, похоже, она не всегда работает:

threads = n
thread_id = 0:n-1
filesize (in bytes) = x

starting position = thread_id*(filesize/threads)
bytes to read = (filesize/threads)

Иногда только для правильных чисел, например 26-байтового файла, разделенного на 9 потоков (я знаю, что это смешно, но только для примера), это не работает в мою пользу. Должен быть лучший способ. Есть идеи?

Ответы [ 3 ]

1 голос
/ 14 февраля 2011

Мне кажется, единственное, чего не хватает, так это тому, что последний поток (поток n-1) должен прочитать до конца файла, чтобы получить байты «модуля» - байты, которые были оставлены делением на threads.В основном:

bytes_to_read = (thread_id == n - 1) ? filesize / threads + filesize % threads
                                     : filesize / threads

В качестве альтернативы вы можете разделить эту дополнительную работу на первые filesize % threads потоки, добавив 1 байт на поток к bytes_to_read - конечно, вам придется корректировать начальные позиции.

0 голосов
/ 14 февраля 2011

Чтобы прочитать каждый байт ровно один раз, последовательно вычислите начальную и конечную позиции, затем вычтите, чтобы получить число байтов:

start_position = thread_id * file_size / n
end_position = (thread_id + 1) * file_size / n
bytes_to_read = end_position - start_position

Обратите внимание, что выражение позиции тщательно выбирается, чтобы дать вам end_position == file_size при thread_id == n-1. Если вы делаете что-то еще, например thread_id * (file_size/n), вам нужно будет рассматривать это как особый случай, как говорит @wuputah.

0 голосов
/ 14 февраля 2011

вы должны сделать что-то вроде:

starting position = thread_id * floor(filesize / threads)
bytes to read = floor(filesize / threads) if thread_id != threads-1
bytes to read = filesize - (threads-1)*floor(filesize / threads) if thread_id = threads - 1
...