
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.142] |
![]() |
|
Страницы: (3) 1 [2] 3 все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Во-первых, при записи можно не ждать, когда установятся головки и под них подойдёт нужный блок, а записать данные в кэш и отчитаться, что операция выполнена. Реальную же запись выполнить, когда будет время.
Во-вторых, если после этого сразу начнётся чтение, можно придержать данные в кэше, прочитать нужные данные, а потом уже выбирать время для записи. Можно накопить данные, и потом записать их в порядке, минимизирующем дёргание головок. Специально для тех, кто не понимает разницу между высокоуровневым чтением из программного буфера и низкоуровневым с диска (встречал и такое), и пытающимся читать данные с диска по одному байту, можно не гонять головку к нужному блоку, а выдавать его прямо из памяти, уменьшив замедление работы с 1000 раз и более всего до 10. Поскольку файлы хранятся на диске по-кластерно, а некоторые даже иногда подвергают диск дефрагментации, можно прочитать дорожку до конца в кэш, и заняться другими делами, по запросам выдавая уже прочитанные блоки. Ну и последнее, многие не знают, но на современных дисках размер блока уже довольно давно не равен 512 байт (у меня в компе размер блока равен 4096 - 8 логических блоков, определяется при сбоях). Более того, реальные кластеры часто пересекают границы физических блоков на диске, и даже переходят с дорожки на дорожку. Чтобы сделать вид, что блок по-прежнему равен 512 байт. Приходится при чтении разбивать физические блоки на логические в кэше, а при записи собирать их обратно. |
Сообщ.
#17
,
|
|
|
OpenGL, т.е. если диск может принять в свой кэш 64MБ, то все равно нужно забивать его мелкими порциями по 64КБ - и это будет по фэншую? А вот если установим свой программный кэш, к примеру в 16МБ, то получим (можем получить) просадку по скорости?
![]() |
![]() |
Сообщ.
#18
,
|
|
Цитата OpenGL @ Если жалкие проценты в быстродействии важны, то проще всего сделать размер буфера конфигурируемым, и на конкретной системе уже и выбирать наиболее подходящий размер. Жалкие проценты никого не волнуют, но размер буфера конфигурируемым я сделал, Дальше задача саппорта, буду делать stress test с файлами 20-25Мега на неделе, выложу, благодарю за хинты, Я пока stand by. |
Сообщ.
#19
,
|
|
|
JoeUser
Цитата JoeUser @ то все равно нужно забивать его мелкими порциями по 64КБ - и это будет по фэншую? Когда я ставил эксперименты то оптимальным на чтение было 256КБ на запись 8МБ. Цитата JoeUser @ А вот если установим свой программный кэш, к примеру в 16МБ, то получим (можем получить) просадку по скорости? Да проседает на проценты. |
Сообщ.
#20
,
|
|
|
Цитата JoeUser @ Цитата OpenGL @ Речь о том, что нет смысла делать буфер большой - 64 кб, например, за глаза и уши, а лучше и того меньше. Возникает резонный вопрос - зачем тогда HDD обеспечивают аппаратным кэшем в 64/32/16/8 MB? ![]() А было время, когда этого не было. В этом случае, ЦП должен был сам, программно, управлять диском в реальном времени. Что не очень удобно, а в ситемах типа Виндус крайне не выгодно. (А я такие опыты производил в ситеме CPM/80. Писал процедуру форматирования дискеток) Поэтому в дивайсы стали устанавливать весьма интеллектуальные контроллеры, а связь с внешним миром организовали через общую память. Для того, чтобы максимальным образом разгрузить центральный процессор. ----- Похожая эволюция затрагивает практически любые дивайсы. Например, сетевые карты. Видео-карты. |
![]() |
Сообщ.
#21
,
|
|
Цитата JoeUser @ OpenGL, т.е. если диск может принять в свой кэш 64MБ, то все равно нужно забивать его мелкими порциями по 64КБ - и это будет по фэншую? А вот если установим свой программный кэш, к примеру в 16МБ, то получим (можем получить) просадку по скорости? Я когда-то экспериментировал, то получал, что начиная с некоторого совсем небольшого размера размер буфера перестаёт ускорять чтение-запись. |
Сообщ.
#22
,
|
|
|
Странно это все, очень странно!
![]() Написал прогу на Си для тестирования различных вариантов буферизированной записи. Тестирование проводил на "живой ОС Win 10x64", т.е. не на виртуальной машине. Сама система крутится на материнском RAID-0 (fake RAID). Запись проводил на дополнительно подключенный HDD c SATA 6Gb/s на интерфейс компа SATA III, и потом другой HDD по USB 3.0. Комп на базе Intel Core i7-3770K, 3.5GHz, 8GB RAM. Для более реальных, как мне показалось, условий - писал в два конкурирующих за I/O (вернее за запись) потока. Вот код: ![]() ![]() #include <stdio.h> #include <stdlib.h> #include <time.h> #include <pthread.h> #include <unistd.h> #define BUFF_LEN_ONE 256*1024 #define BUFF_LEN_TWO 1*1024*1024 void* Write256KB(void* buff) { FILE *fd; struct timespec start, stop; clock_gettime (CLOCK_REALTIME, &start); if ((fd = fopen("F:/one.bin", "wb")) == NULL) { perror("Cannot open file one.bin"); return NULL; }; setvbuf(fd, (char *)buff, _IOFBF, BUFF_LEN_ONE); for (long int i=0; i<128*1024*1024; ++i) fputs("0123456789ABCDEF",fd); fflush(fd); /** в принципе не надо **/ fclose(fd); clock_gettime (CLOCK_REALTIME, &stop); printf ("Delta One: %lu.%lu sec\n",stop.tv_sec - start.tv_sec,stop.tv_nsec - start.tv_nsec); return NULL; } void* Write32MB(void* buff) { FILE *fd; struct timespec start, stop; clock_gettime (CLOCK_REALTIME, &start); if ((fd = fopen("F:/two.bin", "wb")) == NULL) { perror("Cannot open file two.bin"); return NULL; }; setvbuf(fd, (char *)buff, _IOFBF, BUFF_LEN_TWO); for (long int i=0; i<128*1024*1024; ++i) fputs("0123456789ABCDEF",fd); fflush(fd); /** в принципе не надо **/ fclose(fd); clock_gettime (CLOCK_REALTIME, &stop); printf ("Delta Two: %lu.%lu sec\n",stop.tv_sec - start.tv_sec,stop.tv_nsec - start.tv_nsec); return NULL; } int main() { pthread_t one, two; void *buff_one, *buff_two; buff_one = malloc(BUFF_LEN_ONE); buff_two = malloc(BUFF_LEN_TWO); if (pthread_create(&one, NULL, Write256KB, buff_one) != 0) perror("Pthread_create-1 fails"); if (pthread_create(&two, NULL, Write32MB, buff_two) != 0) perror("Pthread_create-2 fails"); if (pthread_join(one,NULL) != 0) perror("Pthread_join-1 fails"); if (pthread_join(two,NULL) != 0) perror("Pthread_join-2 fails"); return 0; } Может с кодом че не так? Но результаты получились странные. Свел их в таблицы для наглядности: Прикреплённая картинка
Прикреплённая картинка
Выводы: 1) Для программы с более одним потоком - операционная система рулит как хочет 2) Для потоков желательно не использовать буфера равных размеров - общее быстродействие программы ухудшается 3) Самый последний тест с равными размерами буферов для USB 3.0 удивляет Критикуйте. Что не так написал или где неправильный вывод сделал. Добавлено ЗЫ: Каждый из тестов запускал по несколько прогонов, тупо чтобы убедиться, что цифры "не пляшут". Как писал выше, с последним тестом с равными буферами для HDD USB - устойчивая разница. Везде разброс между запусками - доли секунды. |
Сообщ.
#23
,
|
|
|
JoeUser
1)У вас процессор отрабатывает за 10 секунд пересылку в буфер ОС. Win7 и далее используют всю свободную память под дисковый кэш. А далее виндоус медленно записывает на диск. Так что с тем что винда, как хочет так и рулит согласен. 2) Цитата JoeUser @ общее быстродействие программы ухудшается Вы табличку неправильно нарисовали. У вас же не скорость в ней, а время. Поэтому не ухудшается, а улучшается. Во-вторых график надо строить не столбчатый, а трёх мерный с вариацией размеров буферов иначе тренд непонятен. В чём смысл двух потоков? Почему не 4 или 5? 3) Чем удивляет? Судя повсему в обоих таблицам скорость 1 и 2 перепутаны с 1 и 2 буфером. Кстати у вас вывод printf("Delta One: не синхротронный и там буквы да и цифры должны плясать чёрти как. |
Сообщ.
#24
,
|
|
|
Цитата Pavia @ )У вас процессор отрабатывает за 10 секунд пересылку в буфер ОС. Win7 и далее используют всю свободную память под дисковый кэш. А далее виндоус медленно записывает на диск. Нет. На на пару тестах, во время их работы, я открывал ProcessExplorer и смотрел загрузку проца нитями - была на протяжении всей записи, но от 1% до 5% максимум. Цитата Pavia @ Вы табличку неправильно нарисовали. У вас же не скорость в ней, а время. Поэтому не ухудшается, а улучшается. Во-вторых график надо строить не столбчатый, а трёх мерный с вариацией размеров буферов иначе тренд непонятен. Да нет, все верно - пара столбцов под один вариант буфферов, следующая пара - под другой, и т.д. - лучший вариант меньший. Помимо того "серая" линия показывает "общее время программы" (иными словами максимально-бОльшее время работы одного из потоков). Аналогично - меньшее время = лучший результат. Цитата Pavia @ Судя повсему в обоих таблицам скорость 1 и 2 перепутаны с 1 и 2 буфером. Ничего не перепутано! Я времена снимал с "Delta ...:". Да, в некоторых случаях второй поток (второй, бОльший буфер) успевал отписываться первым, т.к. завершал раньше. Я все это учитывал. Цитата Pavia @ В чём смысл двух потоков? Почему не 4 или 5? Смысл в том, чтобы каждый из потоков работал не в "тепличных" условиях, а в условиях конкуренции. Два мне показалось для обеспечения конкуренции достаточным. Цитата Pavia @ Кстати у вас вывод printf("Delta One: не синхротронный и там буквы да и цифры должны плясать чёрти как. В моем тесте такого в 99.9% быть не может - т.к. разница между выводами на много больше скорости вывода на консоль, более того - саму еще буферезированную. Кстати - код я привел, можно у себя проверить. Я собирал с помощью gcc version 5.3.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project). |
Сообщ.
#25
,
|
|
|
JoeUser
Цитата JoeUser @ Смысл в том, чтобы каждый из потоков работал не в "тепличных" условиях, а в условиях конкуренции. Два мне показалось для обеспечения конкуренции достаточным. Жесткий запроектированы на временное разделение для 4 потоков. Поэтому 2-х недостаточно. Во-вторых я не понимаю чего вы ожидаете увидеть? Цитата JoeUser @ Нет. На на пару тестах, во время их работы, я открывал ProcessExplorer и смотрел загрузку проца нитями - была на протяжении всей записи, но от 1% до 5% максимум. Дело в том, что ProcessExplorer считает данные блоки как Free. Просто запустите несколько процессов 32-битных или 64 битных которые съедят всю свободную память и данамика записи изменится у вас правда она не отображается. Но на скорость это тоже повлияет. Цитата JoeUser @ Да нет, все верно Так я не про то, что верно не верно. А про-то что вводит в заблуждение. Как на картинах intel vs amd. Скрытый текст ![]() |
Сообщ.
#26
,
|
|
|
Цитата Pavia @ Дело в том, что ProcessExplorer считает данные блоки как Free. Я раскрывал свойство запущенной программы, открывал вкладку Threads и смотрел сколько CPU в % отъедает каждая работающая нить. Какие такие блоки??? Цитата Pavia @ А про-то что вводит в заблуждение. Ну да, хотя давно уже пора запомнить, больше - не значит лучше ![]() Цитата Pavia @ Жесткий запроектированы на временное разделение для 4 потоков. Поэтому 2-х недостаточно. Кто и кем запроектирован для 4-х потоков и почему 2 недостаточно? Цитата Pavia @ Во-вторых я не понимаю чего вы ожидаете увидеть? Какой из потоков с соответствующим размером буфера умудриться свои данные записать быстрее. Потом подумалось об общем быстродействии - что также немаловажно. |
![]() |
Сообщ.
#27
,
|
|
Цитата JoeUser @ Цитата Pavia @ Жесткий запроектированы на временное разделение для 4 потоков. Поэтому 2-х недостаточно. Кто и кем запроектирован для 4-х потоков и почему 2 недостаточно? Потоков лучше всего столько, сколько ядер на машине. |
Сообщ.
#28
,
|
|
|
Цитата sergioK @ Потоков лучше всего столько, сколько ядер на машине. Это когда ядра есть чем занять по вычислениям. |
![]() |
Сообщ.
#29
,
|
|
Чуток подправил для одновременного запуска на разных объёмах буферов. За неимением POSIX-а переиначил потоки и время на плюсовые std:: аналоги. Тестил на SATAшных терабайтниках.
Регулар: ![]() ![]() Using 262144 and 1048576 len buffers: delta two: 22.642 sec | delta one: 24.108 sec Using 262144 and 16777216 len buffers: delta one: 13.658 sec | delta two: 23.652 sec Using 262144 and 536870912 len buffers: delta one: 10.679 sec | delta two: 33.190 sec Using 262144 and 524288 len buffers: delta one: 23.556 sec | delta two: 24.215 sec Using 262144 and 262144 len buffers: delta one: 24.640 sec | delta two: 24.889 sec Using 16777216 and 16777216 len buffers:delta one: 24.022 sec | delta two: 24.270 sec Энкриптед: ![]() ![]() Using 262144 and 1048576 len buffers: delta two: 24.068 sec | delta one: 24.511 sec Using 262144 and 16777216 len buffers: delta one: 13.193 sec | delta two: 22.704 sec Using 262144 and 536870912 len buffers: delta one: 10.568 sec | delta two: 32.802 sec Using 262144 and 524288 len buffers: delta one: 24.850 sec | delta two: 25.351 sec Using 262144 and 262144 len buffers: delta one: 23.470 sec | delta two: 23.867 sec Using 16777216 and 16777216 len buffers:delta one: 23.279 sec | delta two: 23.809 sec Сомпрессед: ![]() ![]() Using 262144 and 1048576 len buffers: delta two: 30.661 sec | delta one: 34.824 sec Using 262144 and 16777216 len buffers: delta two: 20.858 sec | delta one: 46.974 sec Using 262144 and 536870912 len buffers: delta one: 40.822 sec | delta two: 53.165 sec Using 262144 and 524288 len buffers: delta one: 45.717 sec | delta two: 59.511 sec Using 262144 and 262144 len buffers: delta two: 58.195 sec | delta one: 63.441 sec Using 16777216 and 16777216 len buffers:delta two: 30.491 sec | delta one: 31.853 sec Не понимаю, об чём сыр-бор. Понятно же, что результат будет зависеть от конкретики, и синтетические тесты ровным счётом ничего не покажут. Для полноты экспериментов нужно ещё пробовать флажочки из WinAPI. Для фана регулар на 4Г флэшке (NTFS): ![]() ![]() Using 262144 and 1048576 len buffers: delta two: 95.395 sec | delta one: 152.316 sec Using 262144 and 16777216 len buffers: delta two: 118.955 sec| delta one: 182.474 sec Using 262144 and 536870912 len buffers: delta two: 155.706 sec| delta one: 157.165 sec Using 262144 and 524288 len buffers: delta two: 378.902 sec| delta one: 415.027 sec Using 262144 and 262144 len buffers: delta one: 258.895 sec| delta two: 259.765 sec Using 16777216 and 16777216 len buffers:delta two: 87.787 sec | delta one: 152.773 sec |
Сообщ.
#30
,
|
|
|
Qraizer, сенкс, что не поленился
![]() 1) Первый эксперимент - кэш в 1 мег выигрывает у кэша в 256к 2) Второй эксперимент с кэшем в 256к и 16 мегами - дает максимальную общую производительность проги 3) Последний эксперимент - что творит венда с записью на USB с обоими кэшами по 16 мег, только ей известно Цитата Qraizer @ Понятно же, что результат будет зависеть от конкретики, и синтетические тесты ровным счётом ничего не покажут. Согласен. Безапелляционные утверждения о конкретном значении программного кэша (пресловутые 256к) - наводят туман! ![]() |