5

У меня на четырехъядерном ноутбуке Acer Aspire S3 работает программа VBA. Проблема в том, что он использует только 25% процессорного времени (остальные процессы в совокупности используют ~ 1%). Ноутбук работает под управлением Windows 8.0. Выпуск Excel - 2013 (32-разрядная версия). Используется только 55% оперативной памяти, в то время как Excel использует половину из 55%.

Я думаю, может быть, используется только 25%, потому что Excel использует только одно ядро. Однако у меня нет ничего, чтобы поддержать эту теорию. Как я могу ускорить программу?

Благодарю.

5 ответов5

11

Все ниже относится к Excel 2007 и более ранним версиям. Согласно ссылке @ Ƭᴇcʜιᴇ007, размещенной в комментариях выше, в Excel 2013 имеется некоторая встроенная поддержка многопоточности. Тем не менее, предупреждение просто забыть об этом, если вы не опытный программист, по-прежнему применяется.

К сожалению, VBA не поддерживает многопоточность, поэтому ваши вычисления VBA будут ограничены одним ядром вашего процессора.

Однако существует продвинутый метод обмана VBA для запуска нескольких потоков путем генерации файлов VBscript и их одновременного выполнения. Это позволяет обойти эту проблему, запустив ваш код вне процесса Excel и позволяя Windows управлять ресурсами, выделенными различным потокам.

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

Если вы хотите проникнуть в кроличью нору, вот вам интересное сообщение в блоге, которое показывает пример того, как это делается. Имейте в виду: если вы не являетесь опытным программистом, вы можете также забыть эту идею и просто признать, что VBA работает в одном потоке.

Другие ресурсы по переполнению стека для смелых:
https://stackoverflow.com/q/19159025/657668
https://stackoverflow.com/q/5721564/657668

Есть, конечно, другие способы оптимизировать код VBA без использования нескольких потоков. Не видя ваш код, невозможно сделать точные предложения, но вот пара обычных подозреваемых:

  • Загрузите данные из вашего листа в массив для более быстрой обработки. Взаимодействия с рабочим листом являются основным узким местом в исполнении VBA, и их можно минимизировать, работая с массивами.
  • С этим связана проблема, когда Excel пересчитывает рабочую книгу после каждого изменения ячейки. Этого можно избежать, установив Application.Calculation = xlManual . Просто не забудьте установить его обратно в Application.Calculation = xlAutomatic перед выходом из вашего Sub.
6

Мне кажется, что программа, которую вы пытаетесь использовать, является однопоточной, то есть она может использовать только одно ядро, она не знает, что другие существуют. На самом деле нет конкретного способа ускорить это, кроме как купить процессор с более высокой тактовой частотой одного ядра или использовать программу, которая поддерживает многопоточность.

2

Отказ от ответственности: это неправильный ответ, но я нахожу, что многим пользователям необходимо найти этот тип указаний вместе с другими ответами относительно использования только одного ядра, и моя репутация слишком низка, чтобы публиковать ее как комментарий.

Похоже, ваш VBA-скрипт использует только одно ядро, и это может быть хорошо!

Как уже упоминали другие в хороших ответах, я думаю, что важно знать другие аспекты этого вопроса, чтобы помочь вам найти подходящее решение. Так как ты ускоряешь программу?

  • 100% использование процессора в обзоре системы не означает, что ваша программа работает так быстро, как может: возможно, будет сделано много бесполезных вещей, попробуйте поискать «Оптимизация скорости VBA». Любой хороший поисковик даст вам несколько полезных ответов из сети Stack Exchange. Идите на время, потраченное на расчеты, а не на использование процессора.
  • VBA в Excel не обязательно является лучшим инструментом для выполнения работы: для длительных вычислений, вычисляющих числа, может быть полезно экспортировать данные из Excel и использовать другую платформу, в зависимости от ваших навыков программирования. Есть очень много на выбор, некоторые из них прекрасно интегрируются с платформой Microsoft и имеют значительно лучшую достижимую производительность (выполнение бесполезных вещей также применимо и здесь).
  • Запуск 100% CPU, вероятно, не даст вам 4-кратное увеличение скорости по сравнению с только 25%: в зависимости от того, насколько хорошо вы разбьете свои вычисления, вы можете добиться всего лишь 2-кратного повышения на 4 ядрах. Но есть случаи, которые приводят к почти 4-кратному увеличению на 4 ядрах - например, если вычисление для каждой строки полностью не зависит от каких-либо других данных в вашей электронной таблице. Смотрите закон Амдала о Википедии.
  • Возможно, не стоит пытаться использовать больше ядер: хотя в некоторых случаях это может быть полезно, сделать расчет более чем одним ядром может быть (и обычно бывает) на порядок сложнее, требуя некоторого тщательного опыта в методы программирования (см. этот вопрос для общего обзора).
  • Бонус: Возможно, вам вообще не нужно ускорять вашу программу. Если расчет занимает, скажем, три минуты, а вы запускаете его только один раз в день, почему бы не подняться со стула на некоторое время и не напрячь свои жесткие кости? Вы рискуете потратить дни на настройку вашей программы, чтобы иметь возможность запустить ее за две минуты тридцать, что окупается лишь в очень длительной перспективе. Хороший программист тратит время на оптимизацию только тогда, когда это действительно того стоит, поэтому позвольте себе вдохновляться хорошими программистами :)
2

Как говорили другие, изначально VBA не является многопоточным. Если вы хотите ускорить работу, вы можете написать пользовательские функции (UDF) на другом языке.

Я бы порекомендовал вам ExcelDNA и использовать C # или VB.Net. Они очень просты в использовании, если вы уже знаете, как написать C # и можете управлять многопоточностью в UDF.

http://exceldna.codeplex.com/

0

Как уже говорили другие, многопоточность была бы ответом, но это не совсем выполнимое решение, и обновление до 64-битной системы имело бы незначительную разницу. Одна вещь, которую вы можете попробовать сделать, - это повысить приоритет процесса, вы можете увидеть, как это сделать здесь.

Трудно сказать, ускорит ли это ваш сценарий или нет, поскольку в других местах программы может быть еще одно узкое место (например, чтение / запись с диска), но это, по крайней мере, даст Windows знать, что это более высокий приоритет, чем ваш. другие процессы.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .