Я реализовал алгоритм на Android с использованием OpenCL и OpenMP. Реализация OpenMP работает примерно в 10 раз медленнее, чем реализация OpenCL.
- OpenMP: ~ 250 мс
- OpenCL: ~ 25 мс
Но в целом, если я измерил время со стороны java android, у меня примерно столько же времени, чтобы позвонить и получить свои значения.
Например:
Java-код:
// calls C implementation using JNI (Java Native Interface)
bool useOpenCL = true;
myFunction(bitmap, useOpenCL); // ~300 ms, timed with System.nanoTime() here, but omitted code for clarity
myFunction(bitmap, !useOpenCL); // ~300 ms, timed with System.nanoTime() here, but omitted code for clarity
Код C:
JNIEXPORT void JNICALL Java_com_xxxxx_myFunctionNative(JNIEnv * env, jobject obj, jobject pBitmap, jboolean useOpenCL)
{
// same before, setting some variables
clock_t startTimer, stopTimer;
startTimer = clock();
if ((bool) useOpenCL) {
calculateUsingOpenCL(); // runs in ~25 ms, timed here, using clock()
}
else {
calculateUsingOpenMP(); // runs in ~250 ms
}
stopTimer = clock();
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Time in ms: %f\n", 1000.0f* (float)(stopTimer - startTimer) / (float)CLOCKS_PER_SEC);
// same from here on, e.g.: copying values to java side
}
Код Java в обоих случаях выполняется примерно в одно и то же время, около 300 мс. Если быть более точным, elapsedTime
немного больше для OpenCL, то есть OpenCL в среднем медленнее.
Глядя на отдельные среды выполнения OpenMP и реализации OpenCL, версия OpenCL должна быть намного быстрее в целом. Но по какой-то причине есть накладные расходы, которые я не могу найти.
Я также сравнил OpenCL с обычным собственным кодом (без OpenMP), я все же получил те же результаты, с примерно одинаковым временем выполнения в целом, хотя calculateUsingOpenCL
работал как минимум в 10 раз быстрее.
Идеи:
Возможно, графический процессор (в случае OpenCL) в целом менее эффективен, поскольку у него меньше доступной памяти. Есть несколько переменных, которые нам нужно предварительно выделить, которые используются в каждом кадре. Итак, мы проверили время, которое требуется Android для рисования растрового изображения в обоих случаях (OpenMP, OpenCL). В случае OpenCL иногда рисование растрового изображения занимало больше времени (в 3 раза больше), но не на величину, которая бы выровняла общее время выполнения программы.
Использует ли JNI графический процессор для ускорения некоторых вызовов, что может привести к замедлению версии OpenCL?
EDIT:
- Возможно ли, что сборка мусора Java запускается OpenCL, вызывая большие накладные расходы?