Размер буфера в переполнении стека

Я наблюдаю следующее поведение с помощью метода библиотеки C ++ Std std :: ostream :: write ().

Для буферизации данных я использую следующий C ++ API

std::ofstream::rdbuf()->pubsetbuf(char* s, streamsize n)

Это прекрасно работает (проверено с помощью утилиты strace), пока размер данных (размер данных), которые мы записываем в поток файлов, используя

std::ofstream::write (const char* s, datasize n)

Меньше 1023 байта (ниже этого значения записи накапливаются до тех пор, пока буфер не заполнится), но когда размер записываемых данных превышает 1023, буфер не учитывается и данные сбрасываются в файл.

например Если я установлю размер буфера в 10 КБ и запишу около 512 байт за раз, strace покажет, что несколько записей были объединены в одну запись

writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240 ( 10 KB )
writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240
...

но когда я записываю 1024 байта за раз (оставляя буфер фиксированным до 10 КБ), теперь strace показывает мне, что он не использует буфер, и каждый вызов ofstream :: write транслируется для записи системного вызова.

writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024 ( 1KB )
writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024
...

Есть ли какой-нибудь C ++ API Call или Linux Tuning Parameter, который мне не хватает?

5

Решение

Это деталь реализации libstdc ++, реализованная в строке 650 бит / fstream.tcc. По сути, если запись больше 2 ^ 10, буфер будет пропущен.

Если вы хотите обосновать это решение, я предлагаю вам отправить письмо в список разработки libstdc ++.

http://gcc.gnu.org/ml/libstdc++/

2

Другие решения

Похоже, кто-то, пишущий реализацию stdlib, произвел «оптимизацию», не задумываясь об этом. Таким образом, единственный обходной путь для вас будет избегать C ++ API и использовать стандартную библиотеку C.

Это не единственная субоптимальность в реализации стандартной библиотеки C ++ для GNU / Linux: на моей машине malloc() на 100 циклов быстрее, чем стандарт void* operator new (size_t size)

1