Параметры настройки системы Pharo
Я новичок в Stackru и ищу советы и помощь по настройке Pharo 5.0 в среде Windows.
Мой ПК работает под управлением Windows 10, CPU I5-4670K с частотой 4 ГГц и SSD Plextor 512G в качестве диска C, на котором загружается и работает Pharo 5.0.
Ниже приведен набор кодов, которые я использовал для понимания поведения Pharo как в плане производительности, так и в отношении точности вычислений.
| x y |
x := 0.
y := 400000000.
[1 to: 2000000000 do: [ :i |
x := x + 0.2]] timeToRun
Выполнено 2 минуты 8,281 секунды. Если я выбил один ноль из числа итераций, это заняло всего 1.762 секунды. В 10 раз больше итераций использовалось более 70 раз во время выполнения. Кажется, что я попал в системную границу, так что время выполнения между этими двумя случаями вырастет намного больше, чем в 10 раз.
Цените любые советы и помогите настроить виртуальную машину Pharo 5.0, чтобы я мог уменьшить такое неожиданное и нежелательное поведение системы?
ps Во время выполнения диспетчер задач Windows не сообщал об изменениях активности диска. Практически все операции выполняются с использованием оперативной памяти и процессора. Кстати, если у вас нет намного более быстрого ПК, пожалуйста, не пытайтесь добавить еще один ноль к числу итераций, это заняло так много времени, что мне пришлось прервать выполнение.
1 ответ
Добро пожаловать на SO (и на тег smalltalk!)
Первое замечание, что временное y
здесь не играет никакой роли, поэтому мы можем немного упростить фрагмент
| x |
x := 0.
[1 to: 200000000 * 10 do: [ :i |
x := x + 0.2]] timeToRun
с которым вы сравнили
| x |
x := 0.
[1 to: 200000000 * 1 do: [ :i |
x := x + 0.2]] timeToRun
Причина, по которой первая версия не просто 10
раз медленнее, чем второй, что в первом блок переменной i
движется от SmallInteger
домен к LargeInteger
один. Таким образом, каждый раз, когда блок увеличивается i
, когда i
превзошел SmallInteger
граница, сложение i := i + 1
что происходит здесь включает в себя LargeInteger
арифметика, которая медленнее, чем SmallInteger
один.
И сколько раз LargeInteger
арифметика состоится? Ну, чтобы вычислить, что нам нужно только вычесть SmallInteger maxVal
от 200000000 * 10
:
(200000000 * 10) - SmallInteger maxVal = 926,258,177
это означает, что Pharo выполняет такое количество операций с большим целым i
,
Обратите внимание, что если бы мы имели вместо
| x |
x := 0.
[
10 timesRepeat: [1 to: 200000000 * 1 do: [ :i | x := x + 0.2]]
] timeToRun
мы бы потратили около 10
раз скорость одной итерации.
ДОПОЛНЕНИЕ
Пожалуйста, не принимайте объяснение выше, как предполагающее, что LargeInteger
арифметика имеет плохую производительность в Pharo. Напротив, Pharo делает большую работу по обеспечению эффективности таких вычислений.
За кулисами Pharo использует примитивы для этих операций, предоставляя программисту уникальное и последовательное представление и API Integer
арифметика. На самом деле, если вы попытаетесь сделать то же самое на другом диалекте без поддержки VM для LargeInteger
вам придется ждать намного (намного) дольше, чтобы результат был рассчитан.