Так в основном Вы ищете, какие каталоги имеют много файлов? Вот первый удар в нем:
find . -type d -print0 | xargs -0 -n1 count_files | sort -n
, где "count_files" является сценарием оболочки, который делает (благодарит Jonathan)
echo $(ls -a "$1" | wc -l) $1
Это зависит от того, что вы делаете. В общем коде приложения вам следует избегать спин-блокировок.
В низкоуровневых материалах, где вы удерживаете блокировку только для пары инструкций, а задержка важна, мат спин-блокировки будет лучшим решением, чем блокировка . Но такие случаи редки, особенно в приложениях, где обычно используется C #.
В C #, по моему опыту, «спиновые блокировки» почти всегда хуже, чем взятие блокировки - это редкий случай, когда спин-блокировки превосходят блокировку.
Однако это не всегда так. .NET 4 добавляет структуру System.Threading.SpinLock . Это дает преимущества в ситуациях, когда замок удерживается в течение очень короткого времени и неоднократно захватывается. Из документов MSDN на Структуры данных для параллельного программирования :
В сценариях, где ожидание блокировки будет коротким, SpinLock предлагает лучшую производительность, чем другие формы блокировки.
Спиновые блокировки могут превосходит другие механизмы блокировки в тех случаях, когда вы делаете что-то вроде блокировки через дерево - если у вас есть блокировки только на каждом узле на очень и очень короткий период времени, они могут превзойти традиционный замок. Я столкнулся с этим в движке рендеринга с многопоточным обновлением сцены, в какой-то момент - спин-блокировки профилированы так, чтобы превзойти блокировку с Monitor.Enter.
Для моей работы в реальном времени, особенно с драйверами устройств, я довольно часто их использовал. Оказалось, что (когда я в последний раз это рассчитывал) ожидание объекта синхронизации, такого как семафор, привязанный к аппаратному прерыванию, занимает не менее 20 микросекунд, независимо от того, сколько времени на самом деле требуется для возникновения прерывания. Однократная проверка аппаратного регистра с отображением в памяти с последующей проверкой RDTSC (чтобы обеспечить тайм-аут, чтобы вы не блокировали машину) находится в высоком наносекундном диапазоне (в основном, на уровне шума). Для аппаратного подтверждения установления связи, которое вообще не должно занимать много времени, действительно сложно превзойти спин-блокировку.
My 2c: Если ваши обновления удовлетворяют некоторым критериям доступа, тогда они являются хорошими кандидатами для спин-блокировки:
Для всего, что может привести к срабатыванию, вы должны использовать уведомленную структуру блокировки (события, мьютекс, семафоры и т. д.).
Если у вас есть критический для производительности код и , вы определили, что он должен быть быстрее, чем сейчас и , вы определили, что критический фактор это скорость блокировки, тогда было бы неплохо попробовать спин-блокировку. В остальных случаях зачем беспокоиться? Обычные замки легче использовать правильно.
Обратите внимание на следующие моменты:
Большинство реализаций мьютексов вращаются некоторое время, прежде чем поток фактически станет незапланированным. Из-за этого трудно сравнивать эти мьютексы с чистыми спин-блокировками.
Несколько потоков, выполняющих «как можно быстрее» на одной спин-блокировке, займут всю полосу пропускания и резко снизят эффективность вашей программы. Вам нужно добавить крошечное время "сна", добавив петлю в вашу спинку.
Вам вряд ли когда-нибудь понадобится использовать спин-блокировки в коде приложения, во всяком случае, вам следует их избегать.
Я не могу найти никаких причин для использования спин-блокировки в коде C #, работающем в обычном режиме. ОПЕРАЦИОННЫЕ СИСТЕМЫ. Блокировки занятости в основном являются пустой тратой на уровне приложения - вращение может заставить вас использовать весь временной интервал процессора, а блокировка немедленно вызовет переключение контекста, если это необходимо.
Высокопроизводительный код, в котором количество потоков = количество процессоров / ядер, в некоторых случаях может выиграть, но если вам нужна оптимизация производительности на этом уровне, вы, вероятно, создадите 3D-игру следующего поколения, работая на встроенной ОС с плохими примитивами синхронизации. , создавая ОС / драйвер или в любом случае не используя C #.
Я использовал спин-блокировки для фазы остановки сборщика мусора в моем проекте HLVM , потому что они просты и являются игрушкой ВМ. Однако спин-блокировки могут быть контрпродуктивными в этом контексте:
Одна из ошибок производительности в сборщике мусора Glasgow Haskell Compiler настолько раздражает, что носит название « последнее замедление ядра ». Это прямое следствие ненадлежащего использования спин-блокировок в их сборщиках мусора и исключается в Linux из-за его планировщика, но на самом деле эффект может наблюдаться всякий раз, когда другие программы конкурируют за процессорное время.
Эффект очевиден на втором графике здесь и его можно увидеть не только на последнем ядре здесь , где программа Haskell видит снижение производительности за пределами 5 ядер.
Один из вариантов использования спин-локов - если вы ожидаете очень низкую нагрузку, но у вас их будет много. Если вам не нужна поддержка рекурсивной блокировки, спин-блокировка может быть реализована в одном байте, и если зацикленность очень низкая, то потери процессорного цикла будут незначительными.
Для практического применения я часто использую массивы из тысяч элементов, где обновление различных элементов массива может безопасно происходить параллельно. Вероятность того, что два потока одновременно попытаются обновить один и тот же элемент, очень мала (низкий уровень конкуренции), но мне нужна одна блокировка для каждого элемента (у меня их будет много). В таких случаях я обычно выделяю массив ubytes того же размера, что и массив, который я обновляю параллельно, и реализую спинлокинг inline следующим образом (на языке программирования D):
while(!atomicCasUbyte(spinLocks[i], 0, 1)) {}
myArray[i] = newVal;
atomicSetUbyte(spinLocks[i], 0);
С другой стороны, если бы мне пришлось использовать обычные блокировки, мне пришлось бы выделить массив указателей на объекты, а затем выделить объект Mutex для каждого элемента этого массива. В сценариях, подобных описанному выше, это просто расточительно.