Мне кажется, что вам придется загружать файл в память, если вы хотите избежать конфликтов ввода-вывода. Операционная система выполнит некоторую буферизацию, но если вы обнаружите, что этого недостаточно, вам придется сделать это самостоятельно.
Вам правда нужны 32 темы? Предположительно у вас не так много ядер - так что используйте меньше потоков, и вы получите меньше переключения контекста и т. Д.
Все ваши потоки обрабатывают файл от начала до конца? Если да, не могли бы вы эффективно разделить файл на куски? Считайте первые (скажем) 10 МБ данных в память, пусть все потоки обрабатывают их, затем переходят к следующим 10 МБ и т. Д.
Если это не работает для вас, сколько памяти у вас по сравнению с размером файла? Если у вас достаточно памяти, но вы не хотите выделять один огромный массив, вы можете прочитать весь файл в память, но во множество отдельных меньших байтовых массивов. Затем вам нужно написать входной поток, который охватывает все эти байтовые массивы, но это должно быть выполнимо.