Я пишу тестовую программу, используя ArrayFire, работающую на Windows 10 + Nvidia Gtx 970. Программа предназначена для обучения нейронной сети с помощью решателя SGD. Таким образом, основным вычислением является итерация по обновлению параметров сети. Итерация находится в функции с именем step()
.
Программа делает то, что ожидается, за исключением того, что в первую минуту она работает очень медленно. Ниже приведен вывод программы. Первый столбец — прошедшее время.
ArrayFire v3.5.1 (CUDA, 64-bit Windows, build 0a675e8) Platform: CUDA Toolkit 8, Driver: CUDA Driver Version: 8000 [0] GeForce GTX 970, 4096 MB, CUDA Compute 5.2 time epochs training error 5 0.002 5.6124567 6 0.007 5.5981609 7 0.010 5.3560046 8 0.015 5.2485286 9 0.020 5.1370633 10 0.022 5.1081303 .... 52 0.148 3.2528560 53 0.150 3.2425120 54 0.153 3.2180901 55 0.155 3.2048657 56 0.157 3.1949191 57 0.158 3.1816899 58 0.160 3.1717312 59 0.162 3.1597322 60 0.165 3.1370639 60 0.498 2.1359600 61 0.548 2.0685355 61 0.882 1.7098215 62 0.943 1.6575973 62 1.277 1.4156345 63 1.343 1.3845720 63 1.677 1.1789854 64 1.733 1.1549067 64 2.067 1.0162785 .... 71 4.517 0.4732214 71 4.850 0.4522045 72 4.910 0.4501807 72 5.243 0.4355422 73 5.305 0.4307187
Как видите, за первую минуту он не закончил даже 1/5 эпохи. Но через одну минуту он внезапно ускорился и завершил одну эпоху примерно за 4 секунды.
О том же говорят и данные профилирования: в первую минуту среднее время выполнения функции step()
составляет около 500 мс, но после первой минуты оно падает до 6 мс.
Визуальный профилировщик Nvidia показывает, что ядро почти все время бездействует в первую минуту.
Я понятия не имею, что могло вызвать изменение производительности до|после первой минуты. Любая помощь приветствуется.