2016-02-07 2 views
-1

Я пишу программу OpenCL, которую я впервые написал на своем Macbook Pro, и поскольку мой настольный компьютер сильнее, я хотел портировать код и посмотреть, есть ли какие-либо улучшения.OpenCL медленнее на настольном компьютере, чем macbook 13 «

Тот же самый код баллотировался:

Mac: 0.055452s

Win7: 0.359s

характеристики обоих компьютеров: Mac: 2.6GHz Intel Core i5, 8 Гб 1600 МГц DDR3, Intel Iris 1536MB

PC: 3,3 ГГц Intel Core i5-2500K, 8 Гб 1600 МГц DDR3, AMD Radeon HD 6900 Series

Теперь, как вы можете увидеть код побежал на моем Mac почти в 10 раз быстрее, чем на моем настольном ПК.

я приурочил код с помощью

#include<ctime> 
clock_t begin = clock(); 
....// Entire main file 
float timeTaken = (float)(clock() - begin)/CLOCKS_PER_SEC; 
cout << "Time taken: " << timeTaken << endl; 

Если я не ошибаюсь, как CPU и GPU сильнее на ПК. Я смог запустить Battlefield 3 на настройках Ultra с помощью этого настольного компьютера.

Только разница может заключаться в том, что Visual Studio на ПК компилируется с другим компилятором? Я использовал g ++ на своем mac, не уверен, что использует Visual Studio.

Эти результаты не имеют смысла для меня. Ребята, что вы думаете? Если вы хотите, чтобы проверить код, который я могу разместить ссылку GitHub

EDIT: Следующая ссылка GitHub показывает код https://github.com/Batkow/OpenCL/tree/master/OpenCL. PSO_V2 использует тип кодирования, используемые в учебнике из: https://www.fixstars.com/en/opencl/book/OpenCLProgrammingBook/introduction-to-parallelization/

И ПСО упрощает кодирование с использованием пользовательских заголовков из этого GitHub репо: https://github.com/HandsOnOpenCL/Exercises-Solutions ..

Я побежал код на моих друзьях нового i7 портативного компьютера с NVidia Geforce 950M и код был выполнен еще медленнее, чем на моем настольном ПК.

Я действительно понимаю, что код не оптимизирован, поэтому любые намеки на глупые вещи, которые я делаю, пожалуйста, обращайтесь к ним. Например, если цикл while через три разные функции ядра выглядит глупо правильным? Я работаю над тем, чтобы реализовать все это внутри ядра и внутри него цикла, что должно повысить производительность?

ОБНОВЛЕНИЕ: Раскройте код OpenCL/PSO на окнах дома снова. Сроки кода до и после цикла while дают WINDOWS более высокую производительность yay!

clock_t Win7 = 0,027 и Mac = 0,036. Использование внешнего .hpp с классом Util :: Timer Win7 продолжалось: 0,026, а Mac - 0,085.

С момента начала основного файла справа перед циклом while (все инициализации) Mac набрал лучше Windows почти в 10 раз, используя как clock_t, так и Util :: Timer. Итак, узкое место, похоже, стоит на инициализации устройства?

+0

попробуйте прочитать это: [link] (http://stackoverflow.com/questions/21134279/difference-in-performance-between-msvc-and-gcc-for-highly-optimized-matrix-multp) – Incomputable

+1

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

+0

При сравнении разницы между процессором и графическим процессором у вас есть * как минимум *, чтобы исключить передачу памяти из эталона. Как уже упоминалось выше, разместите свой код. –

ответ

0

Visual Studio будет использовать компилятор MSVC, если не указано иное.

Я думаю, что ответ скрыт в ваших поколениях ЦП. На вашем ПК это Sandy Bridge (2-й ген) и на Mac - Haswell (4-й ген). Это разница в 2 поколения.

OpenCL - это одна из вещей, которая значительно развивалась во время этих поколений процессоров Intel (чрезмерная аппаратная поддержка в Haswell).

Просто, чтобы получить доказательство - найдите друга с рабочим столом, оснащенным процессором Haswell, и запустите свои тесты. Рабочий процессор Haswell должен бить ваш Mac один (конечно, если другие аппаратные спецификации и общая загрузка системы будут совпадать).

+0

есть ли способ подтвердить это с моего конца? – Batko

+0

@ Батко попробуйте этот тест http://www.luxrender.net/wiki/LuxMark – DaddyM

+0

Просто попробовал бенчмарк.Win7 дал для CPU + GPU оценку: 4307 и только GPU: 3178 .. В то время как Mac дал для CPU + GPU: 1602 и 1660 только для GPU .. Хм, похоже, что аппаратное обеспечение не является проблемой? Я заметил, что LuxMark сказал, что версии платформы 1.2 для процессора и графического процессора на macbook, в то время как Win7 получил OpenCL 2.0 AMD-APP (1800.8) – Batko

1

Может быть, десятки вещей - то, что делает ядро ​​CL, будет ключевым, и насколько хорошо это работает на разных типах графических процессоров. Или какой компилятор используется

Однако, я думаю, проблема в том, как вы измеряете время. clock() на Windows измеряет «время работы на стену» (другими словами «прошедшее время»), на OSX (и всех других нормальных ОС), он сообщает процессорное время для вашего процесса. Если OSX работает на графическом процессоре [или в отдельном процессе], он не будет считаться CPU-time, где Windows измеряет общее время.

Измерьте время процессора, используя соответствующее время измерения ЦП в Windows (например, GetProcessTimes). Или используйте C++ std::chrono для измерения времени настенных часов в обоих местах.

1

Может быть проблема с пути вы измерения уходящего времени, например, я сделал три различных способа сделать это в моем проекте для разных ОС:

#include <cstdio> 
#include <iostream> 

#if defined(_WIN32) || defined(_WIN64) 
#include <windows.h> 
#elif defined(__linux__) 
#include <time.h> 
#elif defined(__APPLE__) 
#include <mach/mach.h> 
#include <mach/mach_time.h> 
#include <stddef.h> 
#endif 
#if defined(_WIN32) || defined(_WIN64) 
LARGE_INTEGER frequency; // ticks per second 
LARGE_INTEGER t0, t1, t2; // ticks 
LARGE_INTEGER t3, t4; 
#elif defined(__linux__) 
timespec t0, t1, t2; 
timespec t3, t4; 
double us; 
#elif defined(__APPLE__) 
unsigned long t0, t1, t2; 
#endif 
double elapsedTime; 
void refreshTime() { 
#if defined(_WIN32) || defined(_WIN64) 
    QueryPerformanceFrequency(&frequency); // get ticks per second 
    QueryPerformanceCounter(&t1);   // start timer 
    t0 = t1; 
#elif defined(__linux__) 
    clock_gettime(CLOCK_MONOTONIC_RAW, &t1); 
    t0 = t1; 
#elif defined(__APPLE__) 
    t1 = mach_absolute_time(); 
    t0 = t1; 
#endif 
} 

void watch_report(const char *str) { 
#if defined(_WIN32) || defined(_WIN64) 
    QueryPerformanceCounter(&t2); 
    printf(str, (t2.QuadPart - t1.QuadPart) * 1000.0/frequency.QuadPart); 
    t1 = t2; 
    elapsedTime = (t2.QuadPart - t0.QuadPart) * 1000.0/frequency.QuadPart; 
#elif defined(__linux__) 
    clock_gettime(CLOCK_MONOTONIC_RAW, &t2); 
    time_t sec = t2.tv_sec - t1.tv_sec; 
    long nsec; 
    if (t2.tv_nsec >= t1.tv_nsec) { 
    nsec = t2.tv_nsec - t1.tv_nsec; 
    } else { 
    nsec = 1000000000 - (t1.tv_nsec - t2.tv_nsec); 
    sec -= 1; 
    } 
    printf(str, (float)sec * 1000.f + (float)nsec/1000000.f); 
    t1 = t2; 
    elapsedTime = (float)(t2.tv_sec - t0.tv_sec) * 1000.f + 
       (float)(t2.tv_nsec - t0.tv_nsec)/1000000.f; 
#elif defined(__APPLE__) 
    uint64_t elapsedNano; 
    static mach_timebase_info_data_t sTimebaseInfo; 

    if (sTimebaseInfo.denom == 0) { 
    (void)mach_timebase_info(&sTimebaseInfo); 
    } 

    t2 = mach_absolute_time(); 
    elapsedNano = (t2 - t1) * sTimebaseInfo.numer/sTimebaseInfo.denom; 
    printf(str, (float)elapsedNano/1000000.f); 
    t1 = t2; 
    elapsedNano = (t2 - t0) * sTimebaseInfo.numer/sTimebaseInfo.denom; 
    elapsedTime = (float)elapsedNano/1000000.f; 
#endif 
} 
/*This Function will work till you press q*/ 
void someFunction() { 
    while (1) { 
    char ch = std::cin.get(); 
    if (ch == 'q') 
     break; 
    } 
} 

int main() { 
    refreshTime(); 
    someFunction(); 
    watch_report("some function was working: \t%9.3f ms\n"); 
} 
+0

DIdnt получает ваш код для работы, somethign пропустил .. но использовал код из одного ответов здесь: http://stackoverflow.com/questions/17432502/how-can-i-measure-cpu-time-and-wall-clock-time-on-both-linux-windows ... Mac получил walltime 0.085 и процессорное время 0.051, тогда как ПК получил время на стене: 0.354 и процессорное время: 0.203s – Batko

+0

@ Батко моя ошибка Я только что исправил код, добавив недостающие заголовки, а someFunction для теста, похоже, работает со мной на linux. Я могу сказать, что я запускаю эту функцию из своего проекта на Mac, Windows и Linux, и у меня был более или менее сопоставимый результат. – segevara

-1

Другая возможная причина, почему вы можете быть с, что результаты - возможно ваша программа компилируется в OpenCL ver.2.0.

В Windows ваш GPU работает с 2010 года, он поддерживает только OpenCL 1.2.

На OSX ваш Intel GPU поддерживает OpenCL 2.0.

+0

Я сделал тест для Mac и Windows, как вы можете видеть в другом комментарии, и Windows получила гораздо лучший результат. Он сказал, что opencl на Win7 был 2.0 AMD-APP, но только для mac opencl 1.2 – Batko

+0

Ваш AMD GPU поддерживает только 1.2: https://en.wikipedia.org/wiki/List_of_AMD_graphics_processing_units#Radeon_HD_6xxx_Series Если ваша программа использует OpenCL 2.0 функции, такие как совместная виртуальная память/вложенный параллелизм/атомика/трубы и т. д., OpenCL с радостью запускает вашу программу на Intel GPU на Mac, но не сможет использовать ваш GPU на базе Windows. – Soonts

+0

Я выполнил пробный запуск примера01 из https://github.com/HandsOnOpenCL/Exercises-Solutions/tree/master/Solutions/Exercise05/Cpp, который распечатывает информацию об устройстве. И мой процессор и gpu только для поддержки Mac версия 1.2 ... – Batko

0

Вы разместили свои функции синхронизации, но не код OpenCL. Что все приурочено? Большим фактором может быть время компиляции ядра (clCreateProgramFromSource и clBuildProgram). Ваш компьютер может использовать кешированные ядра, а ваш Mac - нет. Правильный способ измерения времени выполнения OpenCL - это использовать события OpenCL.

+0

Как вы уже упоминали, построение программы, по-видимому, является тем, что занимает большую часть времени для меня на платформе Windows. Но также буферы записи немного медленнее. Помимо этого, похоже, что у него одинаковое время выполнения. Я также заметил, что AMD SDK говорит, что у него есть платформа OpenCL 2.0 .. однако мой GPU не совместим с 2.0 .. И я не могу найти в Интернете какой-либо AMD SDK для opencl 1.2 ни – Batko

1

Его функция clock() просто подсчитывает циклы тактовых импульсов ЦП. Ваш хост-код может вызвать ядро ​​и затем переспать. И это время сна обычно не учитывается функцией часов, даже если вы выполняете ядро. Таким образом, это означает, что функция часов учитывает только время выполнения хост-кода, а не ядро ​​openCL. Вам нужно использовать функцию, которая учитывает время настенных часов, а не тактовые циклы процессора.

Смежные вопросы