Уже существует несколько хороших ответов, обеспечивающих обходные решения для awk
неспособность сделать нежадные соответствия, таким образом, я предоставляю некоторую информацию об альтернативном способе сделать это с помощью Perl совместимых регулярных выражений (PCRE). Обратите внимание что самое простое "соответствие и печать" awk
сценарии могут легко быть повторно реализованы в perl
использование -n
параметр командной строки и более сложные сценарии могут быть преобразованы с a2p Awk в переводчика Perl.
Perl имеет нежадный оператор, который может использоваться в сценариях Perl и чем-либо, что использует PCRE. Например, также реализованный в grep's GNU -P
опция.
PCRE не идентичен регулярным выражениям Perl, но это очень близко. Это - популярный выбор библиотеки регулярных выражений для многих программ, потому что это очень быстро, и улучшения Perl к расширенным регулярным выражениям очень полезны.
От perlre (1) страница справочника:
By default, a quantified subpattern is "greedy", that is, it will match
as many times as possible (given a particular starting location) while
still allowing the rest of the pattern to match. If you want it to
match the minimum number of times possible, follow the quantifier with
a "?". Note that the meanings don't change, just the "greediness":
*? Match 0 or more times, not greedily
+? Match 1 or more times, not greedily
?? Match 0 or 1 time, not greedily
{n}? Match exactly n times, not greedily (redundant)
{n,}? Match at least n times, not greedily
{n,m}? Match at least n but not more than m times, not greedily
Ответ Peterph действительно заставлял меня рассмотреть проблему возможного кэширования далее. После рытья вокруг, я все еще не могу сказать наверняка, делают ли кто-либо, некоторые или все SD-карты это, но я действительно думаю, что это возможно.
Однако я не полагаю, что кэширование включило бы данные, больше, чем блок стирания. Чтобы быть действительно уверенным, я повторил тест с помощью блока на 16 МБ вместо 64 КБ. Это является 1/250-м суммарный объем карты на 4 ГБ. Потребовалось ~8 часов, чтобы сделать это 10,000 раз. Если бы износ, выравнивающийся, прилагает все усилия для распределения нагрузки вокруг, это означает, что каждый физический блок использовался бы 40 раз.
Это не очень, но исходная точка теста должна была продемонстрировать эффективность износа, выравнивающегося путем показа, что я не мог легко повредить карту через повторные записи скромных объемов данных к тому же (очевидному) местоположению. IMO предыдущий тест на 64 КБ был, вероятно, реален - но 16 МБ нужно быть. Система сбросила данные к аппаратным средствам, и аппаратные средства сообщили о записи без ошибки. Если бы это было обманом, то карта ни для чего не была бы хороша, и она не может кэшировать 16 МБ нигде, но в основной памяти, которая является тем, что тест предназначается для выделения.
Хотелось бы надеяться, 10 000 записей 16 МБ, каждого достаточно, чтобы продемонстрировать, что даже на брендовой карте заднего конца (оцените: CDN за 5$), выполнение корневой файловой системы rw 24/7, который пишет скромные объемы данных ежедневно, не будет изнашивать карту в разумном сроке. 10 000 дней составляют 27 лет..., и карта прекрасна все еще...
Если я становился заплаченным для разработки систем, которые сделали более тяжелую работу, чем которая, я захочу сделать по крайней мере несколько тестов для определения, сколько времени карта может прослужить. Моя догадка - то, что с одним как это, которое имеет низкую скорость записи, могли потребоваться недели, месяцы или годы непрерывной записи в максимальной скорости (факт нет кучи сравнительных тестов этого вида, онлайн говорит с тем, что это было бы очень длительное дело).
Относительно подтверждения карты все еще хорошо, я больше не думаю с помощью badblocks
в он - конфигурация по умолчанию, является соответствующим. Вместо этого я сделал это этот путь:
badblocks -v -w -b 524288 -c 8
То, что означает тестировать использование блока на 512 КБ, повторилось 8 раз (= 4 МБ). Так как это - разрушительный тест rw, это, вероятно, было бы хорошо как мое домотканое относительно выделения устройства, если используется в непрерывном цикле.
Я также создал файловую систему на нем, скопировал в файле на 2 ГБ, diff
'd файл против оригинала и затем - так как файл был .iso - смонтировал его как изображение и просмотрел файловую систему в этом.
Карта прекрасна все еще. Который должен, вероятно, ожидаться после всех...
Я думаю стресс-тестирование, SD-карта находится в общем, проблематичном, учитывая 2 вещи:
износ, выравнивающийся, нет никаких гарантий, что одна запись к следующему на самом деле осуществляет те же физические местоположения на SD. Помните, что большинство систем SD на месте активно берет блок, поскольку мы знаем это и перемещение физического местоположения, которое поддерживает его вокруг на основе воспринятого "износа", которому было подвергнуто каждое местоположение.
различные технологии (MLC по сравнению с SLC) другая проблема, которую я вижу с этим, являются различием в технологиях. Типы SLC SSD я ожидал бы иметь намного более долгую жизнь по сравнению с разнообразием MLC. Также существуют намного более трудные допуски на MLC, что Вы просто не должны иметь дело с на SLC's, или по крайней мере они намного более терпимы к сбою таким образом.
Проблема с MLC состоит в том, что данная ячейка может сохранить несколько значений, биты по существу сложены с помощью напряжения, вместо того, чтобы просто быть физическим +5V или 0V, например, таким образом, это может привести к большому потенциалу большой частоты отказов, чем их эквивалент SLC.
Я нашел эту ссылку, которая обсуждает немного о том, сколько времени аппаратные средства могут прослужить. Это названо: Знайте Свои SSD - SLC по сравнению с MLC.
SLC ssds может быть вычислен, по большей части, для проживания где угодно между 49 годами и 149 годами, в среднем, наилучшими оценками. Тестирование Memoright может проверить SSD на 128 ГБ, имеющий продолжительность жизни износостойкости записи сверх 200 лет со средней записью 100 ГБ в день.
Это - то, где дизайн mlc терпит неудачу. Ни один не был выпущен на данный момент. Никто действительно не исследовал, какую продолжительность жизни гарантируют с mlc за исключением того, что, это будет значительно ниже. Я получил несколько различных верований, которые составляют в среднем от 10 до 1 продолжительности жизни в пользу дизайна slc. Консервативное предположение - то, что большинство оценок продолжительности жизни прибудет между 7 и 10 годами, в зависимости от продвижения ‘алгоритмов выравнивания износа’ в контроллерах каждого производителя.
Для провожения сравнения посредством циклов записи slc имел бы время жизни 100 000 полных циклов записи по сравнению с mlc, который имеет время жизни 10 000 циклов записи. Это могло значительно увеличиться в зависимости от дизайна ‘выравнивания износа’, используемого.
fstrim
впоследствии, Вы полностью отключили динамический износ, выравнивающийся [Вам было бы трудно находить SD-карту на уровне конечного пользователя со статическим износом, выравнивающимся] путем маркировки каждой страницы, как используется.)
– Jason C
20.10.2013, 21:47
Просто добавление некоторых точек к ответу slm - отмечает, что они существуют больше для SSD, чем для "немых" SD-карт, так как SSD играют намного более грязные приемы с Вашими данными (например, дедупликация):
Вы пишете 64 КБ в начало устройства - это само имеет две проблемы:
ячейки флэш-памяти обычно имеют блоки стирания размера от 16 КБ (более вероятно в 128-512KB диапазоне, хотя). Что означает, что этому нужен кэш, по крайней мере, этого размера. Следовательно запись 64 КБ, кажется, не достаточно мне.
для низкопроизводительного (чтение "непредприятие") решения (и я ожидал бы это еще больше для карт SD/CF, чем для SSD) производители могут принять решение сделать начало устройства более эластичным для износа, чем остальные начиная с важных структур - таблица разделов, и FAT на единственном разделе на устройстве (большинство карт памяти использует эту установку) - расположены там. Таким образом тестирование начала карты могло бы быть смещено.
fdatasync()
действительно не гарантирует, что данные записаны в физическую среду (хотя это, вероятно, прилагает все усилия то, что находится под контролем ОС) - см. страницу справочника:
Блоки вызова, пока устройство не сообщает, что передача завершилась
Я не был бы чрезмерно удивлен, оказалось ли, что существует маленький конденсатор, который может обеспечить энергию для записи кэшированных данных к флэш-памяти в случае потери внешнего питания.
В любом случае, под предположением о кэше, присутствующем на карте (см. мой ответ на свой вопрос на SU), пишущий 64 КБ и синхронизируя (с fdatasync()
) кажется, не убеждает достаточно с этой целью. Даже без любого "резервного копирования питания" встроенное микропрограммное обеспечение могло бы все еще играть его небезопасный и сохранить данные незаписанными некоторое время, дольше, чем один будет ожидать (так как в типичных вариантах использования оно не должно создавать проблемы).
Вы могли бы хотеть считать данные прежде, чем записать новый блок и сравнить его, только удостовериться, что это действительно работает (и используйте очищенный буфер для чтения, если Вы достаточно параноики).
read
в Вашем тесте является ненужным, он не добавляет информации и не относится к тесту цикла записи. Для истинного теста Вы захотите считать назад блок, который Вы просто записали, и проверьте его, если Вы не знаете наверняка, что контроллер может обнаружить и сообщить все виды отказа.
– Jason C
21.10.2013, 07:22
Существует много проблем с Вашим тестом, некоторые нечеткие, некоторые нет. Это также зависит от Вашей цели. Два тонких, вид нечетких проблем:
Однако это возможно педантично. Более серьезный:
badblocks
показать Вам привело страницы к сбою на флэш-памяти; все обнаружения отказов и последующие отображения страницы сделаны контроллером и очевидны для ОС. Вы могли получить некоторую информацию от УМНОГО, если поддержка дисков, это (я не знаю ни о каких SD-картах, которые поддерживают его, возможно, существуют карты флэш-памяти более высокого качества, которые делают).Износ, Выравнивающийся: основной вопрос - то, что износ, выравнивающийся, является главной переменной в Вашем тесте. Это происходит на контроллере (обычно), и в любом случае его очевидные даже для прямого устройства ищут + чтение-запись. В Вашем примере Вы на самом деле не знаете состояние выравнивания износа (в частности, команды ДЛЯ ОБРЕЗКИ были недавно даны к свободным блокам?)...
Для динамического износа, выравнивающегося (существующий в фактически всех устройствах хранения на уровне конечного пользователя) на Вашем устройстве, затем, это могло быть в любом состоянии: В одном экстремальном значении ни одна из страниц не отмечена как свободная, и таким образом, единственные страницы, с которыми должен работать контроллер, являются теми в зарезервированном пространстве (если таковые имеются). Обратите внимание, что, если там резервируется пространство на устройстве, оно должно будет перестать работать полностью, прежде чем Вы начнете гарантироваться сбои на записях страницы (предположение, что нет никаких других страниц, отмеченных как свободные остающиеся). В другом экстремальном значении каждая страница отмечена как свободная, в этом случае у Вас теоретически должна быть каждая страница на сбое устройства, прежде чем Вы начнете видеть отказы при записи.
Для статического износа, выравнивающегося (который SSD имеют тенденцию иметь, SD-карты имеют тенденцию не иметь, и карты флэш-памяти, варьируются): нет действительно никакого пути вокруг этого кроме повторной записи в каждую страницу на устройстве.
... Другими словами, существуют детали выравнивания износа, которые у Вас нет способа знать и конечно никакой способ управлять - особенно, используется ли динамический износ, выравнивающийся, используется ли статический износ, выравнивающийся, и сумма пространства, зарезервированного на устройстве для износа, выравнивающегося (который не является видимым прошлым контроллер [или драйвер в некоторых случаях, как M-Systems старый DiskOnChip]).
SLC/MLC: Что касается SLC по сравнению с MLC, это оказывает очень прямое влияние на пределы, которые Вы ожидали бы видеть, но общая процедура выравнивания износа и процедура тестирования являются тем же для обоих. Многие поставщики не публикуют, являются ли их устройства SLC или MLC для их более дешевых потребительских товаров, хотя любой флеш-накопитель, который требует 100k + предел цикла на страницу, является вероятным SLC (упрощенный компромисс является SLC = износостойкость, MLC = плотность).
Кэширование: Что касается кэширования, это немного сомнительно. На уровне ОС, в общем случае, конечно, fsync/fdatasync не гарантирует, что данные на самом деле записаны. Однако я думаю, что безопасно предположить, что это (или по крайней мере контроллер принял на себя обязательство делать так, т.е. запись не будут глотать в кэше), в этом случае, поскольку съемные диски обычно разрабатываются для шаблона общего использования, "извлекаются" (размонтирование> синхронизация) затем удаляют (отключение питания). В то время как мы не знаем наверняка, образованное предположение говорит, что безопасно предположить, что синхронизация гарантирует, что запись абсолютно произойдет, особенно в записи-> синхронизация-> чтение назад (если бы это не было, то диски были бы ненадежны после того, как извлекаются). Нет никакой другой команды вне 'синхронизации', которая может быть выпущена на, извлекаются.
В контроллере что-либо возможно, но предположение выше также включает предположение, что контроллер, по крайней мере, ничего не делает, "усложнил" достаточно для риска потерей данных после синхронизации. Возможно, что контроллер может, скажем, буферизовать и записи группы или не записать данные, если те же данные переписываются (ограниченно). В программе ниже, мы чередуемся между двумя различными блоками данных и выполняем синхронизацию перед чтением назад конкретно для нанесения поражения разумному механизму кэширования контроллера. Однако, конечно, нет никаких гарантий и никакого способа знать, но мы можем сделать разумные предположения на основе нормального использования этих устройств и нормальных/распространенных механизмов кэширования.
Тестирование:
К сожалению, истина, если Вы не знаете, что устройство не имеет никакого зарезервированного пространства и не делает статического выравнивания, нет никакого способа окончательно протестировать предел цикла определенной страницы. Однако самое близкое, которое можно получить, следующим образом (не предположите статический износ, выравнивающийся):
Первая вещь, которую необходимо сделать, заполнить всю карту данными. Это важно, и является основной переменной, которую оставили в Вашем исходном тесте. Это отмечает, столько же блокируется возможный, сколько используется кроме любого зарезервированного пространства (к которому у Вас нет способа получить доступ). Обратите внимание, что мы работаем со всем устройством (который это уничтожит все данные по), поскольку работающий с единственным разделом только влияет на одну определенную область на устройстве:
dd if=/dev/urandom bs=512k of=/dev/sdb conv=fsync oflag=sync
Если Вы - тип индикатора выполнения:
pv -pterb -s <device_size> /dev/urandom | dd bs=512k of=/dev/sdb conv=fsync oflag=sync
Править: Поскольку карты с 4 МБ стирают блоки, попробуйте это за более быструю запись:
dd if=/dev/urandom bs=4M of=/dev/sdb conv=fsync oflag=direct,sync iflag=fullblock
Затем, затем можно записать тестовую программу цикла следующим образом, использовав O_DIRECT
и O_SYNC
(и возможно параноидальное, избыточное использование fsync()
) для вырезания как можно большей буферизации ОС и кэширования из изображения и, теоретически, пишут непосредственно в контроллер и ожидают, пока это не сообщает, что операция закончилась:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
using namespace std;
static const int BLOCK_SIZE = 512;
static const int ALIGNMENT = 512;
static const int OFFSET = 1024 * ALIGNMENT; // 1024 is arbitrary
int main (int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s device\n", argv[0]);
return 1;
}
int d = open(argv[1], O_RDWR | O_DIRECT | O_SYNC);
if (d == -1) {
perror(argv[1]);
return 1;
}
char *block[2], *buffer;
int index = 0, count = -1;
// buffers must be aligned for O_DIRECT.
posix_memalign((void **)&(block[0]), ALIGNMENT, BLOCK_SIZE);
posix_memalign((void **)&(block[1]), ALIGNMENT, BLOCK_SIZE);
posix_memalign((void **)&buffer, ALIGNMENT, BLOCK_SIZE);
// different contents in each buffer
memset(block[0], 0x55, BLOCK_SIZE);
memset(block[1], 0xAA, BLOCK_SIZE);
while (true) {
// alternate buffers
index = 1 - index;
if (!((++ count) % 100)) {
printf("%i\n", count);
fflush(stdout);
}
// write -> sync -> read back -> compare
if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
perror("lseek(w)");
else if (write(d, block[index], BLOCK_SIZE) != BLOCK_SIZE)
perror("write");
else if (fsync(d))
perror("fsync");
else if (lseek(d, OFFSET, SEEK_SET) == (off_t)-1)
perror("lseek(r)");
else if (read(d, buffer, BLOCK_SIZE) != BLOCK_SIZE)
perror("read");
else if (memcmp(block[index], buffer, BLOCK_SIZE))
fprintf(stderr, "memcmp: test failed\n");
else
continue;
printf("failed after %i successful cycles.\n", count);
break;
}
}
Отметьте это O_DIRECT
, буферы должны быть соответственно выровненные. 512-байтовые границы обычно достаточны. Можно скомпилировать с:
g++ -O0 test.cpp -o test
Добавить -D_POSIX_C_SOURCE=200112L
при необходимости.
Затем после заполнения устройства полностью как выше, просто оставьте работавшим ночь:
./test /dev/sdb
512 байтов, выровненные записи прекрасны, который даст Вам одну всю страницу, стертую и переписанную. Вы могли значительно ускорить тест при помощи большего размера блока, но затем это становится сложным для прибытия в конкретные результаты.
Я в настоящее время тестирую на довольно потрепано выглядящей карте флэш-памяти PNY на 4 ГБ, которую я вчера нашел на тротуаре (казалось, был тем, что оставили http://www3.pny.com/4GB-Micro-Sleek-Attach---Purple-P2990C418.aspx).
Вышеупомянутая программа является по существу ограниченной версией badblocks
и Вы не видели бы отказы, пока все зарезервированное пространство не было исчерпано. Поэтому ожидание (с 1 страницей, записанной на повторение), состоит в том, что вышеупомянутая процедура, в среднем, должна перестать работать в reserved_page_count * write_cycle_limit повторения (снова, износ, выравнивающийся, является главной переменной). Это - слишком плохие карты флэш-памяти, и SD-карты обычно не поддерживают УМНЫЙ, который имеет способность сообщить о зарезервированном размере пространства.
Между прочим, fsync
по сравнению с fdatasync
не имеет никакого значения для блочного устройства, пишет, что Вы делаете в целях этого теста. Ваш open()
режимы важны.
Если Вам любопытно на предмет технических деталей; вот все, плюс что Вы могли бы хотеть знать (больше) о внутренних работах SD-карт: https://www.sdcard.org/downloads/pls/simplified_specs/part1_410.pdf
Править: Байты по сравнению со Страницами: В контексте этих типов тестов важно думать о вещах с точки зрения страниц, не байтов. Может быть очень неправильно сделать противоположное. Например, на SanDisk 8 ГБ SD, размер страницы согласно контроллеру (доступный через /sys/classes/mmc_host/mmc?/mmc?:????/preferred_erase_size
) полные 4 МБ. Запись 16 МБ (выровненный к границам 4 МБ), затем, стирает/пишет 4 страницы. Однако при записи четырем единственным байтам каждый при смещениях 4 МБ друг от друга также стирает/пишет 4 страницы.
Это неточно, затем чтобы сказать, что "Я протестировал с записями 16 МБ", поскольку это - тот же объем износа как, "Я протестировал с 4 побайтовыми записями". Более точно, "Я протестировал с записями на 4 страницы".
dd
сбои после писания 250 МБ. Повреждение не появилось до окончания цикла включения и выключения питания. Карта флэш-памяти PNY остается незатронутой после ~30mil повторения. Я изменил программу выше (не отраженный в коде выше, однако) для записи в случайные 16kB-выровненные местоположения каждый раз вместо того же, но я сделал это после ~4mil проходы на SD. Повторно протестирует с новой картой.
– Jason C
22.10.2013, 07:35
dd
на той карте сделал его мимо метки 250 МБ и производительности записи увеличенным снова до полного 4MB/sec к областям после той точки. Я ожидаю, что производительность будет непредсказуема, тем не менее, в то время как блоки продолжают переставляться. Я не сказал бы, что карта уничтожается, но это, конечно, не в 100%.
– Jason C
22.10.2013, 07:35
badblocks
не покажет, что Вы привели страницы к сбою на флэш-памяти. Это не правильный инструмент для этого задания, и Вы не можете использовать его для нахождения отказавших страниц на флэш-памяти. Когда контроллер обнаружит отказ, он внутренне отметит страницу как плохую и повторно отобразит его на страницу в зарезервированном пространстве. Все это происходит позади контроллера и не видимо Вам, даже в дампе неструктурированного устройства, вообще. Вы могли добраться, некоторая информация от контроллера, если УМНЫЙ поддерживается. Физический порядок данных по устройству не соответствует порядку байтов, которые Вы видите при выполнении IO на устройстве. – Jason C 21.10.2013, 10:55dd
не удалось записать мимо о метке 250 МБ. На третьемdd
делайте попытку его, сделал это прошлыми 250 МБ и после того как это сделало, производительность записи, увеличенная снова в тех областях. Я не сказал бы, что карта уничтожается, но это, конечно, не в 100%. – Jason C 22.10.2013, 07:19