Запуск scipy.integrate.ode в многопроцессорном пуле приводит к огромному результату

Я использую python scipy.integrate для моделирования 29-мерной линейной системы дифференциальных уравнений. Поскольку мне нужно решить несколько проблемных экземпляров, я подумал, что могу ускорить их, выполняя вычисления параллельно, используя multiprocessing.Pool. Поскольку между потоками нет общих данных или синхронизации, проблема неловко параллельна, я думал, что это должно работать. Однако после того, как я написал код для этого, у меня были очень странные измерения производительности:

  • Однопоточный, без jacobian: 20-30 мс за вызов
  • Однопоточный, с jacobian: 10-20 мс за вызов
  • Многопоточный, без jacobian: 20-30 мс за вызов
  • Многопоточный, с jacobian: 10-5000 мс за вызов

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

Эффект кажется зависящим от системы

Я попробовал тот же код на другом компьютере, и я не видел этого эффекта.

Обе машины использовали Ubuntu 64 бит, Python 2.7.6, scipy версии 0.18.0 и numpy версии 1.8.2. Я не видел изменчивости с процессором Intel (R) Core (TM) i5-5300U с процессором 2,30 ГГц. Я видел проблему с Intel (R) Core (TM) i7-2670QM CPU @2.20GHz.

Теория

Одна мысль заключалась в том, что между процессорами может быть общий кэш, и, параллельно его запуская, я не могу вместить два экземпляра матрицы jacobian в кеш, поэтому они постоянно сражаются друг с другом, чтобы кэш замедлял друг друга по сравнению с тем, если они запускаются серийно или без якобиана. Но это не миллионная система. Якобиан представляет собой матрицу 29x29, которая занимает 6728 байт. Кэш уровня 1 на процессоре 4 x 32 KB, намного больше. Существуют ли какие-либо другие общие ресурсы между процессорами, которые могут быть виноваты? Как мы можем проверить это?

Еще одна вещь, которую я заметил, заключается в том, что каждый процесс python, по-видимому, занимает несколько сотен процентов от процессора. Это означает, что код уже распараллелен в какой-то момент (возможно, в низкоуровневой библиотеке). Это может означать, что дальнейшее распараллеливание не помогло бы, но я не ожидал такого резкого спада.

Код

Было бы неплохо опробовать больше машин, чтобы увидеть, могут ли (1) другие люди вообще замедлиться, и (2) каковы общие черты систем, где происходит замедление. Код выполняет 10 испытаний двух параллельных вычислений, используя многопроцессорный пул размером два, распечатывая время на вызов scipy.ode.integrate для каждого из 10 испытаний.

'odeint with multiprocessing variable execution time demonsrtation'

from numpy import dot as npdot
from numpy import add as npadd
from numpy import matrix as npmatrix
from scipy.integrate import ode
from multiprocessing import Pool
import time

def main():
    "main function"

    pool = Pool(2) # try Pool(1)
    params = [0] * 2

    for trial in xrange(10):
        res = pool.map(run_one, params)
        print "{}. times: {}ms, {}ms".format(trial, int(1000 * res[0]), int(1000 * res[1]))

def run_one(_):
    "perform one simulation"

    final_time = 2.0
    init_state = [0.1 if d < 7 else 0.0 for d in xrange(29)]
    (a_matrix, b_vector) = get_dynamics()

    derivative = lambda dummy_t, state: npadd(npdot(a_matrix, state), b_vector)
    jacobian = lambda dummy_t, dummy_state: a_matrix
    #jacobian = None # try without the jacobian

    #print "jacobian bytes:", jacobian(0, 0).nbytes

    solver = ode(derivative, jacobian)
    solver.set_integrator('vode')
    solver.set_initial_value(init_state, 0)

    start = time.time()
    solver.integrate(final_time)
    dif = time.time() - start

    return dif

def get_dynamics():
    "return a tuple (A, b), which are the system dynamics x' = Ax + b"

    return \
    (
        npmatrix([
        [0, 0, 0, 0.99857378006, 0.053384274244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, 1, -0.003182219341, 0.059524655342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, -11.570495605469, -2.544637680054, -0.063602626324, 0.106780529022, -0.09491866827, 0.007107574493, -5.20817921341, -23.125876742495, -4.246931301528, -0.710743697134, -1.486697327603, -0.044548215175, 0.03436637817, 0.022990248611, 0.580153205353, 1.047552018229, 11.265023544535, 2.622275290571, 0.382949404795, 0.453076470454, 0.022651889536, 0.012533628369, 0.108399390974, -0.160139432044, -6.115359574845, -0.038972389136, 0, ],
        [0, 0, 0.439356565475, -1.998182296753, 0, 0.016651883721, 0.018462046981, -0.001187470742, -10.778778281386, 0.343052863546, -0.034949331535, -3.466737362551, 0.013415853489, -0.006501746896, -0.007248032248, -0.004835912875, -0.152495086764, 2.03915052839, -0.169614300211, -0.279125393264, -0.003678218266, -0.001679708185, 0.050812027754, 0.043273505033, -0.062305315646, 0.979162836629, 0.040401368402, 0.010697028656, 0, ],
        [0, 0, -2.040895462036, -0.458999156952, -0.73502779007, 0.019255757332, -0.00459562242, 0.002120360732, -1.06432932386, -3.659159530947, -0.493546966858, -0.059561101143, -1.953512259413, -0.010939065041, -0.000271004496, 0.050563886711, 1.58833954495, 0.219923768171, 1.821923233098, 2.69319056633, 0.068619628466, 0.086310028398, 0.002415425662, 0.000727041422, 0.640963888079, -0.023016712545, -1.069845542887, -0.596675149197, 0, ],
        [-32.103607177734, 0, -0.503355026245, 2.297859191895, 0, -0.021215811372, -0.02116791904, 0.01581159234, 12.45916782984, -0.353636907076, 0.064136531117, 4.035326800046, -0.272152744884, 0.000999589868, 0.002529691904, 0.111632959213, 2.736421830861, -2.354540136198, 0.175216915979, 0.86308171287, 0.004401276193, 0.004373406589, -0.059795009475, -0.051005479746, 0.609531777761, -1.1157829788, -0.026305051933, -0.033738880627, 0, ],
        [0.102161169052, 32.057830810547, -2.347217559814, -0.503611564636, 0.83494758606, 0.02122657001, -0.037879735231, 0.00035400386, -0.761479736492, -5.12933410588, -1.131382179292, -0.148788337148, 1.380741054924, -0.012931029503, 0.007645723855, 0.073796656681, 1.361745395486, 0.150700793731, 2.452437244444, -1.44883919298, 0.076516270282, 0.087122640348, 0.004623192159, 0.002635233443, -0.079401941141, -0.031023369979, -1.225533436977, 0.657926151362, 0, ],
        [-1.910972595215, 1.713829040527, -0.004005432129, -0.057411193848, 0, 0.013989634812, -0.000906753354, -0.290513515472, -2.060635522957, -0.774845915178, -0.471751979387, -1.213891560083, 5.030515136324, 0.126407660877, 0.113188603433, -2.078420624662, -50.18523312358, 0.340665548784, 0.375863242926, -10.641168797333, -0.003634153255, -0.047962774317, 0.030509705209, 0.027584169642, -10.542357589006, -0.126840767097, -0.391839285172, 0.420788121692, 0, ],
        [0.126296110212, -0.002898250629, -0.319316070797, 0.785201711657, 0.001772374259, 0.00000584372, 0.000005233812, -0.000097899495, -0.072611454126, 0.001666291957, 0.195701043078, 0.517339177294, 0.05236528267, -0.000003359731, -0.000003009077, 0.000056285381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [-0.018114066432, 0.077615035084, 0.710897211118, 2.454275059389, -0.012792968774, 0.000040510624, 0.000036282541, -0.000678672106, 0.010414324729, -0.044623231468, 0.564308412696, -1.507321670112, 0.066879720068, -0.000023290783, -0.00002085993, 0.000390189123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [-0.019957254425, 0.007108972111, 122.639137999354, 1.791704310155, 0.138329792976, 0.000000726169, 0.000000650379, -0.000012165459, -8.481152717711, -37.713895394132, -93.658221074435, -4.801972165378, -2.567389718833, 0.034138340146, -0.038880106034, 0.044603217363, 0.946016722396, 1.708172458034, 18.369114490772, 4.275967542224, 0.624449778826, 0.738801257357, 0.036936909247, 0.020437742859, 0.176759579388, -0.261128576436, -9.971904607075, -0.063549647738, 0, ],
        [0.007852964982, 0.003925745426, 0.287856349997, 58.053471054491, 0.030698062827, -0.000006837601, -0.000006123962, 0.000114549925, -17.580742026275, 0.55713614874, 0.205946900184, -43.230778067404, 0.004227082975, 0.006053854501, 0.006646690253, -0.009138926083, -0.248663457912, 3.325105302428, -0.276578605231, -0.455150962257, -0.005997822569, -0.002738986905, 0.082855748293, 0.070563187482, -0.101597078067, 1.596654829885, 0.065879787896, 0.017442923517, 0, ],
        [0.011497315687, -0.012583019909, 13.848373855148, 22.28881517216, 0.042287331657, 0.000197558695, 0.000176939544, -0.003309689199, -1.742140233901, -5.959510415282, -11.333020298294, -14.216479234895, -3.944800806497, 0.001304578929, -0.005139259078, 0.08647432259, 2.589998222025, 0.358614863147, 2.970887395829, 4.39160430183, 0.111893402319, 0.140739944934, 0.003938671797, 0.001185537435, 1.045176603318, -0.037531801533, -1.744525005833, -0.972957942438, 0, ],
        [-16.939142002537, 0.618053512295, 107.92089190414, 204.524147386814, 0.204407545189, 0.004742101706, 0.004247169746, -0.079444150933, -2.048456967261, -0.931989524708, -66.540858220883, -116.470289129818, -0.561301215495, -0.022312225275, -0.019484747345, 0.243518778973, 4.462098610572, -3.839389874682, 0.285714413078, 1.40736916669, 0.007176864388, 0.007131419303, -0.097503691021, -0.083171197416, 0.993922379938, -1.819432085819, -0.042893874898, -0.055015718216, 0, ],
        [-0.542809857455, 7.081822285872, -135.012404429101, 460.929268260027, 0.036498617908, 0.006937238413, 0.006213200589, -0.116219147061, -0.827454697348, 19.622217613195, 78.553728334274, -283.23862765888, 3.065444785639, -0.003847616297, -0.028984525722, 0.187507140282, 2.220506417769, 0.245737625222, 3.99902408961, -2.362524402134, 0.124769923797, 0.142065016461, 0.007538727793, 0.004297097528, -0.129475392736, -0.050587718062, -1.998394759416, 1.072835822585, 0, ],
        [-1.286456393795, 0.142279456389, -1.265748910581, 65.74306027738, -1.320702989799, -0.061855995532, -0.055400100872, 1.036269854556, -4.531489334771, 0.368539277612, 0.002487097952, -42.326462719738, 8.96223401238, 0.255676968878, 0.215513465742, -4.275436802385, -81.833676543035, 0.555500345288, 0.612894852362, -17.351836610113, -0.005925968725, -0.078209662789, 0.049750119549, 0.044979645917, -17.190711833803, -0.206830688253, -0.638945907467, 0.686150823668, 0, ],
        [0, 0, 0, 0, 0, -0.009702263896, -0.008689641059, 0.162541456323, 0, 0, 0, 0, 0, 0, 0, 0, -0.012, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [-8.153162937544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, -3.261265175018, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, 0, 0.17441246156, -3.261265175018, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.01, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, -3.261265175018, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8.5, -18, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, ],
        [0, 0, 0, -8.153162937544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -8.5, -18, 0, 0, 0, 0, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 0.699960862226, 0.262038222227, 0.159589891262, 0.41155156501, -1.701619176699, -0.0427567124, -0.038285155304, 0.703045934017, 16.975651534025, -0.115788018654, -0.127109026104, 3.599544290134, 0.001229743857, 0.016223661959, -0.01033400498, -0.00934235613, -6.433934989563, 0.042639567847, 0.132540852847, -0.142338323726, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, -37.001496211974, 0.783588795613, -0.183854784348, -11.869599790688, -0.106084318011, -0.026306590251, -0.027118088888, 0.036744952758, 0.76460150301, 7.002366574508, -0.390318898363, -0.642631203146, -0.005701671024, 0.003522251111, 0.173867535377, 0.147911422248, 0.056092715216, -6.641979472328, 0.039602243105, 0.026181724138, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 1.991401999957, 13.760045912368, 2.53041689113, 0.082528789604, 0.728264862053, 0.023902766734, -0.022896554363, 0.015327568208, 0.370476566397, -0.412566245022, -6.70094564846, -1.327038338854, -0.227019235965, -0.267482033427, -0.008650986307, -0.003394359441, 0.098792645471, 0.197714179668, -6.369398456151, -0.011976840769, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 1.965859332057, -3.743127938662, -1.962645156793, 0.018929412474, 11.145046656101, -0.03600197464, -0.001222148117, 0.602488409354, 11.639787952728, -0.407672972316, 1.507740702165, -12.799953897143, 0.005393102236, -0.014208764492, -0.000915158115, -0.000640326416, -0.03653528842, 0.012458973237, -0.083125038259, -5.472831842357, 0, ],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ],
        ])
    , 
        npmatrix([1.0 if d == 28 else 0.0 for d in xrange(29)])
    )



if __name__ == "__main__":
    main()

Результат вывода

Вот пример вывода, который демонстрирует проблему (каждый пробег немного отличается). Обратите внимание на большую изменчивость времени выполнения (на два порядка!). Опять же, все это уходит, если я либо использую пул размером 1 (или запускаю код без пула), либо если я не использую явный jacobian в вызове integrate.

  • раз: 5847мс, 5760мс
  • раз: 4177 мс, 3991 м.
  • раз: 229 мс, 36 мс
  • раз: 1317мс, 1544мс
  • раз: 87 мс, 100 мс
  • раз: 113 мс, 102 мс
  • раз: 4747мс, 5077мс
  • раз: 597 мс, 48 мс
  • раз: 9 мс, 49 мс
  • раз: 135 мс, 109 мс

Ответ 1

Это подразумевается как отформатированный комментарий относительно математического фона, выраженного в комментариях @Dietrich. Поскольку он не затрагивает вопрос программирования, я намерен удалить этот ответ через некоторое время, пока не надует щедрость.

Как отметил @Dietrich, вы можете точно решить свой ODE, поскольку если

x' = A*x,

то точное решение

x(t) = exp(A*t)*x0

Уже я бы сказал, что точное решение всегда превосходит численное приближение, но это действительно может быть быстрее, чем численное интегрирование. Как вы отметили в комментарии, вы беспокоитесь об эффективности. Поэтому не вычисляйте матричную экспоненту для каждого t: вычислите eigensystem A только один раз:

A*v_i = L_i*v_i

затем

x(t) = sum_i c_i*v_i*exp(L_i*t),

и коэффициенты c_i можно определить из линейных уравнений

x0 = sum_i c_i*v_i.

Теперь, имея неоднородный член, не сильно изменится, если ваша матрица не сингулярна:

x' = A*x + b
(x - A^(-1)*b)' = A*(x - A^(-1)*b)

поэтому мы можем решить однородное уравнение для y = x - A^(-1)*b и на последнем этапе восстановить x = y + A^(-1)*b.

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

>>> np.linalg.det(A)
0.0
>>> np.linalg.det(A[:-1,:-1])
1920987.0461154305

А также обратите внимание, что конечная строка A - это все нули (это является причиной особенности A). Таким образом, последнее измерение x является постоянным (или линейно изменяется из-за b).

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


Ниже будет немного умозрительно, см. также оговорку в конце.

В случае ввода пользователем A и b все может стать более сложным. Найти нулевую строку/столбец в вашей матрице было бы легко, но A может быть сингулярным, хотя ни одна из его строк/столбцов не равна нулю. Я не эксперт в этом вопросе, но я думаю, что ваш лучший выбор - использовать что-то похожее на анализ основных компонентов: преобразование вашей системы уравнений в соответствии с собственной системой A. Мои последующие мысли по-прежнему предполагают, что A является диагонализируемым, но главным образом потому, что я не знаком с декомпозицией особых значений. В реалистических случаях я ожидал бы, что ваши матрицы будут диагонализуемыми, даже если сингулярными.

Итак, я предполагаю, что матрица A может быть разложена как

A = V * D * V^(-1),

где D - диагональная матрица, содержащая собственные значения A, а столбцы из V - собственные векторы A, соответствующие каждому соответствующему собственному значению. То же самое разложение можно получить в numpy с помощью

DD,V = np.linalg.eig(A)
D = np.asmatrix(np.diag(DD))

Я обычно предпочитаю использовать ndarray вместо матриц, но этот способ V*D*np.linalg.inv(V) действительно будет соответствовать матричному произведению трех матриц, а не дважды называть np.dot.

Теперь заново перепишите свое уравнение:

x' = A*x + b
x' = V*D*V^(-1)*x + b
V^(-1)*x' = D*V^(-1)*x + V^(-1)*b

Определяя вспомогательные переменные

X = V^(-1)*x
B = V^(-1)*b

получаем

X' = D*X + B

то есть. обычная неоднородная форма, но теперь D - диагональная матрица, содержащая собственные значения A в диагонали.

Так как A сингулярно, некоторые из собственных значений равны нулю. Ищите нулевые элементы в D (ну, вы можете сделать это уже с DD от eig()), и вы будете знать, что они ведут себя тривиально во время эволюции времени. Остальные переменные ведут себя хорошо, хотя в этот момент мы видим, что уравнения для x развязаны из-за диагонали D, поэтому вы можете интегрировать каждый независимо и аналитически. Для этого вам нужно сначала перейти от вашего начального условия x0 к X0 = np.linalg.inv(V)*x0, затем после решения уравнений вернуться к x = V*X.

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

Ответ 2

Исходя из изменчивости времени выполнения, которое вы отправили для машины, показывающей проблему, мне интересно, что еще делает этот компьютер в то время, когда вы запускаете свой тест. Вот когда я запускал ваш код на сервере AWS r3.large(2 ядра, 15 ГБ ОЗУ), который обычно запускает интерактивные сеансы R, но в настоящее время в основном не работает:

  • раз: 11 мс, 11 мс
  • раз: 9 мс, 9 мс
  • раз: 9 мс, 9 мс
  • раз: 9 мс, 9 мс
  • раз: 10 мс, 10 мс
  • раз: 10 мс, 10 мс
  • раз: 10 мс, 10 мс
  • раз: 11 мс, 10 мс
  • раз: 11 мс, 10 мс
  • раз: 9 мс, 9 мс

Возможно ли, что ваша машина обменивается, и вы этого не знаете? vmstat 5 предоставит вам много информации об обмене входов и выходов, но не о выселении кеша.

Intel делает очень хорошие инструменты для мониторинга - по два за раз - тысячи разных типов операций и ошибок, происходящих в процессоре, включая выселение кеша L2, - но они немного пожарные: там это информация, генерируемая каждый микросекунда - или чаще - и вам нужно решить, что вы собираетесь контролировать, и как часто вы хотите, чтобы прерывание доставляло числа в ваше программное обеспечение. Вероятно, потребуется много прогонов, чтобы сузить статистику, которую вы хотите отслеживать, и вам все равно придется отфильтровать шум, создаваемый операционной системой, и все остальное, что работает в то время. Это трудоемкий процесс, но если вы выполните его до конца и запустите много разных тестов, вы поймете, что происходит.

Но это - общие ресурсы кэша в процессоре - действительно ваш вопрос? Похоже, вы просто хотите понять, почему у вас есть переменное время выполнения на одной машине, и, во-вторых, почему многопоточность медленнее на обеих машинах, чем однопоточная. У меня все в порядке? Если нет, я отредактирую свой ответ, и мы сможем поговорить о кеше процессора, отслеживании кэша и когерентности кэша.

Итак, что касается изменчивости на процессоре процессора i7-2670QM, я бы начал с htop, vmstat 5 и iostat 5, чтобы убедиться, что машина делает то, чего вы не понимаете. Такая изменчивость говорит о том, что исполняемый файл застопорился, потому что процессор занят чем-то другим: уходит в сеть и не находит общий ресурс, которого он ожидает, не может подключиться к DNS-серверу, получая отказы от kerbios: это может быть много вещей включая аппаратные сбои с жесткого диска, который постоянно reset. О, и переместите вашу программу в /dev/shm и cd там, прежде чем вы начнете ее. Это не поможет вам, если есть библиотеки Python в плохом месте на диске, но по крайней мере у вас не будет проблем с вашим локальным каталогом. Сообщите, что вы найдете, и мы можем сделать дальнейшие предложения.

Ваш второй вопрос, который я вижу, который, возможно, с того, где вы начали, является причиной того, что ваша программа медленнее, если вы запускаете многопоточную, чем однопоточную. Это большая тема, которая будет намного больше в фокусе, если мы сможем увидеть, как вы многопоточили ее. Но даже до того, как мы это сделаем, вы должны понять, что есть несколько вещей, которые могут привести к тому, что многопоточная программа будет работать медленнее, чем однопоточная программа, и она может иметь столько же общего с инфраструктурой поддержки вокруг ваших программных библиотек и вызовы операционной системы, которые вы делаете - как ваша программа. Просто потому, что вам не нужны мьютексы, это не значит, что библиотеки и операционная система не нуждаются в них, когда они вызываются из многопоточного приложения. Блокировка мьютекса - это дорогостоящая операция, особенно когда разные потоки вращаются между разными ядрами.

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

Ответ 3

на моем скомпилированном ядре Linux:

  • раз: 8 мс, 7 мс
  • раз: 5 мс, 4 мс
  • раз: 4 мс, 4 мс
  • раз: 8 мс, 8 мс
  • раз: 4 мс, 4 мс
  • раз: 5 мс, 4 мс
  • раз: 4 мс, 8 мс
  • раз: 8 мс, 8 мс
  • раз: 8 мс, 8 мс
  • раз: 4 мс, 5 мс

Intel (R) Core (TM) i5-4300U CPU @1,90 ГГц

убедитесь, что ваш процессор работает с фиксированной скоростью, noswap. /tmp устанавливается в ОЗУ.