Вопрос пользователя заключается в том, что при использовании многопоточности в Delphi 2010 на компьютере с процессором Intel Core i7 и Windows 7 x64, разница во времени выполнения кода с использованием одного потока и нескольких потоков незначительна. Пользователь ожидает более существенного ускорения, однако фактическое время выполнения остается примерно одинаковым (около 12 секунд). В контексте предоставлено решение проблемы, которое указывает на узкие места в использовании многопоточности.
Основные моменты из контекста:
Пользователь запускает 10 потоков для выполнения одной и той же задачи.
Задача состоит в выполнении цикла, который вызывает функцию IntToStr для каждого числа от 1 до 10 миллионов.
В коде используется класс TMyThread, который наследуется от TThread и переопределяет метод Execute.
При запуске нескольких потоков используется приоритет tpTimeCritical и маскирование потока для привязки к определенным ядрам процессора.
В качестве меры времени используется GetTickCount.
Подтвержденный ответ:
Основная проблема заключается в том, что операции с памятью, такие как выделение и освобождение, являются узким местом. Когда в качестве задачи используется вычисление математической функции (например, Cos(a)), многопоточность работает эффективно. Однако, если задача связана с операциями памяти, например, выделение и освобождение памяти, многопоточная версия работы становится медленнее, чем однопоточная.
В случае использования IntToStr в цикле, происходит временное создание строк, которые затем освобождаются, что и приводит к узкому месту в многопоточной обработке. Многопоточный менеджер памяти добавляет дополнительные проверки, которые могут замедлить работу программы, особенно если операции с памятью являются "горячей точкой".
Рекомендации:
Используйте другие задачи для многопоточности, которые не связаны с интенсивными операциями по работе с памятью.
Рассмотрите возможность использования других менеджеров памяти, например, TopMM, который лучше масштабируется на многопроцессорных системах.
Избегайте использования приоритета tpTimeCritical, если это не абсолютно необходимо, и не вмешивайтесь в управление приоритетами и маскирование потоков, если не имеете глубоких знаний в этой области.
Примеры кода:
Вот пример кода, который демонстрирует использование многопоточности без интенсивных операций с памятью:
procedure TForm1.DoTestMath;
var
i: Integer;
a: Double;
begin
a := 0;
for i := 1 to 10000000 do
a := Cos(a);
end;
И пример кода, который демонстрирует проблемы с многопоточностью из-за операций с памятью:
procedure TForm1.DoTestMemory;
var
i: Integer;
p: Pointer;
begin
for i := 1 to 10000000 do begin
GetMem(p, 10);
FreeMem(p);
end;
end;
Заключение:
При использовании многопоточности в Delphi 2010 важно понимать, какие операции выполняются в задачах, и как они могут быть затруднены из-за конкурентного доступа к ресурсам, таким как менеджер памяти. Используя правильные алгоритмы и инструменты, можно добиться существенного ускорения выполнения программ за счет параллельных вычислений.
Контекст вопроса заключается в том, что многопоточность в Delphi 2010 не приводит к ожидаемому ускорению программы из-за узких мест, связанных с операциями с памятью, и предлагаются рекомендации по оптимизации.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS