Это вызвано асинхронной очередью запуска, связанной с запусками ядра GPU.
Когда вы указываете numba передать ядро GPU:
matmul[(256,256),(16,16)](a1,b1,c1)
Этот запрос переходит в очередь, ипоток ЦП (т. е. python), который выдал этот вызов ядра, может продолжаться, даже если ядро GPU еще не завершено или даже не запущено.
Среда выполнения CUDA ставит эти запросы в очередь и выдает их, так как GPU готов кбольше работы.
То, что вы наблюдаете изначально во время очень быстрого увеличения цикла for, - это очередь, заполняемая рабочими запросами.Это не отражает фактического времени, которое требуется графическому процессору для выполнения работы.
В конечном итоге очередь заполняется, и среда выполнения CUDA останавливает поток ЦП (т. Е. Python) в точке запуска ядра до появления очереди.слот открывается.В этот момент цикл for может продолжаться еще одну итерацию.Именно в этот момент (возможно, около 1028 итераций) вы начинаете видеть «замедление».После этого цикл for продолжается на приблизительно скорости, с которой ядра GPU выполняются и удаляются из очереди обработки.
Здесь нечего исправлять;это ожидаемое поведение.
Если вы хотите, чтобы цикл for выполнялся только с той скоростью, с которой фактически выполняются ядра графического процессора, то вам нужно вставить синхронизирующую функцию в цикл for.
Например, numba предоставляет numba.cuda.synchronize () Так что, если вы измените свой цикл for следующим образом:
for i in range(2000):
matmul[(256,256),(16,16)](a1,b1,c1)
cuda.synchronize()
count +=1
print(count)
Вы увидите, что цикл for продолжится с фактическойскорость завершения работы графического процессора, а не скорость «заполнения очереди».