|
|
|
| Всем привет!!!
Вот у нас есть программа к примеру....
#include <stdio.h>
#include <errno.h>
#define BUF_SIZE 256
int main (int argc, char *argv [])
{
FILE *in_file, *out_file;
char rec [BUF_SIZE];
size_t bytes_in, bytes_out;
if (argc != 3) {
printf ("Usage: cpC file1 file2\n");
return 1;
}
in_file = fopen (argv [1], "rb");
if (in_file == NULL) {
perror (argv [1]);
return 2;
}
out_file = fopen (argv [2], "wb");
if (out_file == NULL) {
perror (argv [2]);
return 3;
}
/* Process the input file a record at a time. */
while ((bytes_in = fread (rec, 1, BUF_SIZE, in_file)) > 0) {
bytes_out = fwrite (rec, 1, bytes_in, out_file);
if (bytes_out != bytes_in) {
perror ("Fatal write error.");
return 4;
}
}
fclose (in_file);
fclose (out_file);
return 0;
}
Объясните мне пож почему BUF_SIZE 256 а не скажем 4096, и от чего это зависит | |
|
|
|
|
|
|
|
для: like-nix
(09.07.2007 в 17:54)
| | Ну если отвечать всем влом попробую продолжить свои изыскания сам ;-).
Рассматривая конкретно этот пример размер буфера можно сделать кратным как размеру буфера стандартной библиотеки (хз, можно в доках поискать, но, наверно, кратно 256), так и размеру кластера файловой системы (думаю, во всех размер кластера кратен 256). В некоторых случаях (если ОС стара и убога или ты работаешь на низком уровне) это (кратность) может оптимизировать обращения к диску, но с современных ОС считываемые с диска данные буферизуются, кажется, не менее, чем дважды (дисковый кэш, и файловый буфер стандартной библиотеки), это не считая собственного кэша HDD. Так что эта кратность особо ни на что не повлияет. Верны ли эти предположения? Тогда 256 является оптимально?
Если обратиться к нативе апе то чтение и запись в файл осущ с помощью системных вызовов
NtWriteFile
NTSYSAPI
NTSTATUS
NTAPI
NtWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
и
NtReadFile
NTSYSAPI
NTSTATUS
NTAPI
NtReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
У обоих этих вызовов есть буфер и чем меньше мы делаем этот самый буфер тем больше вызовов получаем а на кождый вызов тратится время те на файл 4000 байт с буфером чтения/запись 256 байт будет истрачено 16 выззовов а с буфером 4096 один. Теперь я думаю где предел указания буфера и нужно ли его привязывать к кратности кластера в файловой системе. Верно ли это? И как посчитать системные вызовы NtReadFile/NtWriteFile этой программы? | |
|
|
|
|
|
|
|
для: like-nix
(10.07.2007 в 12:55)
| | Что мне нравится в программировании, так это его схожесть с естественными науками. Ученый придумывает модель изучаемого явления а потом сравнивает результаты, полученные из рассчета на модели с экспериментальными данными. Если совпадение есть, значит модель правильная. В программировании то же самое - сначала мысленно представляешь себе как работает программа и что она должна выдать на выходе, потом запускаешь её и сравниваешь полученный результат. Если совпало - значит ты правильно понимаешь, что происходит.
Ты уже мысленно представил что там и как происходит, так сделай и вторую часть - поставь эксперимент. Лучшее средство для этого - профайлер (profiler). Замерь время работы с разным размером буфера (в том числе и не кратным 256).
Думаю, что разница будет не существенна в достаточно широком диапазоне значений буфера. Хотя размер в 256 выглядит, по-моему, глупо. Ведь размер сектора на HDD - 512.
Насчет того как посчитать число системных вызовов - можно попробовать утилиты типа filemon от sysinternals. http://www.microsoft.com/technet/sysinternals/fileanddiskutilities.mspx | |
|
|
|