💡 Инструкция: Выберите один ответ из пяти. На работу отведено 85 минут. После завершения откроются правильные ответы, объяснения и результаты по темам.
Вопрос 2 из 30
Какой контрольный тест лучше всего проверит правило, связанное с `@threads for i in eachindex(x)`?
Julia Julia · Потоки Threads Копировать
using Base.Threads
function threaded_sum(x)
partial = zeros(Float64, nthreads())
@threads for i in eachindex(x)
partial[threadid()] += x[i]
end
return sum(partial)
end
@show nthreads() threaded_sum(rand(100_000))
Проверить на отдельном примере, что сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Проверить на отдельном примере, что `Threads.@threads` сохраняет порядок итераций и закрепляет каждую итерацию за тем же thread id при повторном запуске.
Проверить на отдельном примере, что `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Проверить на отдельном примере, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Проверить на отдельном примере, что потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Вопрос 4 из 30
Как проверить, что новая реализация `@threads for i in eachindex(x)` не изменила обещанное пользователю поведение?
S=\sum_{k=1}^{p}S_k
Приёмка должна подтвердить, что `Threads.@threads` сохраняет порядок итераций и закрепляет каждую итерацию за тем же thread id при повторном запуске.
Приёмка должна подтвердить, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Приёмка должна подтвердить, что `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Приёмка должна подтвердить, что потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Приёмка должна подтвердить, что сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Вопрос 17 из 30
Что нужно подтвердить отдельным примером для `@spawn sum(@view x[r])`?
Julia Julia · Разбиение работы Копировать
using Base.Threads
function chunksum(x, chunks)
tasks = map(chunks) do r
@spawn sum(@view x[r])
end
return sum(fetch, tasks)
end
x = rand(1_000_000)
ranges = Iterators.partition(eachindex(x), 100_000)
@show chunksum(x, collect(ranges))
Проверить на отдельном примере, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Проверить на отдельном примере, что минимально возможный блок работы даёт лучший баланс нагрузки, поскольку накладные расходы планировщика малы по сравнению с почти каждый полезной операцией.
Проверить на отдельном примере, что `Threads.@threads` сохраняет порядок итераций и закрепляет каждую итерацию за тем же thread id при повторном запуске.
Проверить на отдельном примере, что размер блока работы выбирают с учётом неоднородности задач и накладных расходов; один элемент на задачу способен утонуть в планировании.
Проверить на отдельном примере, что атомарная операция защищает конкретное чтение-изменение-запись, но не делает атомарным составной инвариант из нескольких переменных.
Вопрос 22 из 30
Что нужно подтвердить отдельным примером для `BLAS.set_num_threads(1)`?
Julia Julia · Границы применимости Копировать
using Base.Threads, LinearAlgebra
BLAS.set_num_threads(1)
function batch_norm(mats)
out = Vector{Float64}(undef, length(mats))
@threads for i in eachindex(mats)
out[i] = opnorm(mats[i])
end
return out
end
@show batch_norm([rand(100,100) for _ in 1:8])
Проверить на отдельном примере, что `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Проверить на отдельном примере, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Проверить на отдельном примере, что ускорение близко к числу потоков независимо от пропускной способности памяти и последовательной части алгоритма.
Проверить на отдельном примере, что потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Проверить на отдельном примере, что сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Вопрос 26 из 30
Как нужно интерпретировать `@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)`, не добавляя к коду лишних гарантий?
Q_{parallel}=Q_{reference}
Julia Julia · Сопровождение проекта Копировать
using Base.Threads, Test
function parallel_map(f, xs)
out = similar(xs)
@threads for i in eachindex(xs)
out[i] = f(xs[i])
end
return out
end
xs = collect(1:10_000)
@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)
Сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Один детерминированный прогон модульных тестов достаточен для сопровождения многопоточного кода; стресс-тест и последовательный эталон редко находят новые ошибки.
`Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Вопрос 27 из 30
Какой эксперимент отличит настоящий механизм `@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)` от случайного результата одного запуска?
Julia Julia · Сопровождение проекта Копировать
using Base.Threads, Test
function parallel_map(f, xs)
out = similar(xs)
@threads for i in eachindex(xs)
out[i] = f(xs[i])
end
return out
end
xs = collect(1:10_000)
@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)
Проверить на отдельном примере, что потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Проверить на отдельном примере, что сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Проверить на отдельном примере, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Проверить на отдельном примере, что один детерминированный прогон модульных тестов достаточен для сопровождения многопоточного кода; стресс-тест и последовательный эталон редко находят новые ошибки.
Проверить на отдельном примере, что `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Вопрос 28 из 30
Какую гарантию должна сохранить правка участка с `@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)`?
Julia Julia · Сопровождение проекта Копировать
using Base.Threads, Test
function parallel_map(f, xs)
out = similar(xs)
@threads for i in eachindex(xs)
out[i] = f(xs[i])
end
return out
end
xs = collect(1:10_000)
@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)
Сохранить в реализации правило: Гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Сохранить в реализации правило: Сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Сохранить в реализации правило: Потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Сохранить в реализации правило: `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.
Сохранить в реализации правило: Один детерминированный прогон модульных тестов достаточен для сопровождения многопоточного кода; стресс-тест и последовательный эталон редко находят новые ошибки.
Вопрос 29 из 30
Как проверить, что новая реализация `@test parallel_map(x -> x^2, xs) == map(x -> x^2, xs)` не изменила обещанное пользователю поведение?
Q_{parallel}=Q_{reference}
Приёмка должна подтвердить, что потоки полезны для вычислительно независимых участков и библиотек, которые не создают собственную конкуренцию; ускорение ограничено последовательной долей и памятью.
Приёмка должна подтвердить, что один детерминированный прогон модульных тестов достаточен для сопровождения многопоточного кода; стресс-тест и последовательный эталон редко находят новые ошибки.
Приёмка должна подтвердить, что гонка возникает при несогласованном доступе к общему изменяемому состоянию; локальный аккумулятор с последующим объединением часто проще общей записи.
Приёмка должна подтвердить, что сопровождение многопоточного кода требует стресс-тестов, детерминированного последовательного эталона и метрик, иначе редкая гонка возвращается после безобидного рефакторинга.
Приёмка должна подтвердить, что `Threads.@threads` распределяет итерации между потоками, но не обещает фиксированного потока или порядка; тело должно быть независимо либо синхронизировано.