Как указано в документации, и Адонис уже упоминает об этом, запись может выполняться только одним потоком за раз. Вы не добьетесь увеличения производительности за счет параллелизма, более того, вам следует беспокоиться о производительности только в том случае, если это актуальная проблема, потому что одновременная запись на диск может фактически снизить вашу производительность (вероятно, в меньшей степени для твердотельных накопителей, чем для жестких дисков).
Базовый носитель в большинстве случаев (SSD, HDD, сеть) является однопоточным - на самом деле на аппаратном уровне нет такой вещи, как поток, потоки - это не что иное, как абстракция.
В вашем случае носитель - SSD. В то время как SSD внутренне может записывать данные в несколько модулей одновременно (они могут достигать уровня параллелизма, при котором записи могут быть такими же быстрыми и даже превосходить чтение), внутренние структуры данных сопоставления являются общим ресурсом и поэтому конкурируют, особенно при частых обновлениях, таких как параллельные пишет. Тем не менее, обновления этой структуры данных происходят довольно быстро, поэтому беспокоиться не о чем, если только это не станет проблемой.
Но помимо этого, это всего лишь внутренняя часть SSD. Снаружи вы общаетесь через интерфейс Serial ATA, то есть по одному байту за раз (фактически пакеты в структуре информации кадра, FIS). Поверх этого находится ОС / файловая система, которая снова имеет, вероятно, конкурирующую структуру данных и / или применяет собственные средства оптимизации, такие как кэширование с отложенной записью.
Кроме того, поскольку вы знаете, что такое ваш носитель, вы можете оптимизировать его специально для этого, а твердотельные накопители действительно работают быстро, когда один поток записывает большой кусок данных.
Таким образом, вместо использования нескольких потоков для записи вы можете создать большой буфер в памяти (возможно, рассмотреть файл с отображением в память) и одновременно записывать в этот буфер. Сама память не используется, если вы гарантируете, что каждый поток обращается к собственному адресному пространству буфера. Как только все потоки выполнены, вы записываете этот буфер на SSD (не требуется при использовании файла с отображением в память).
См. Также это хорошее резюме о разработке для SSD: Резюме - что каждый программист должен знать о твердотельных накопителях
Смысл выполнения предварительного выделения (или, точнее, file_.setLength()
, который фактически отображается на ftruncate
) заключается в том, что изменение размера файла может использовать дополнительные циклы, и вы, возможно, не захотите этого избежать. Но опять же, это может зависеть от ОС / файловой системы.
person
Gerald Mücke
schedule
07.08.2017