Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.140.108] |
|
Сообщ.
#1
,
|
|
|
Теперь пытаюсь поработать с C++ AMP. Windows 7, VS 2012. В программе из книги C++ AMP
#include <string> #include <iostream> #include <Windows.h> #include <memory.h> #include <stdio.h> #include <time.h> #include <amp.h> #include <ppl.h> using namespace std; using namespace concurrency; void AddArrays(int n, const double* const pA, const double* const pB, double* const pC) { clock_t start, finish, duration; start = clock(); for(int i = 0; i < n; ++i) { pC[i] = pA[i] + pB[i]; } finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета без OpenMP" << endl; } void AddArraysAmp(int n, const int* const pA, const int* const pB, int* const pC) { clock_t start, finish, duration; start = clock(); array_view<int, 1> a(n, pA); array_view<int, 1> b(n, pB); array_view<int, 1> c(n, pC); parallel_for_each(c.extent, [=](index<1> idx) restrict(amp) { c[idx] = a[idx] + b[idx]; }); finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета C++ AMP" << endl; } int main() { setlocale(LC_ALL, ""); int n = 15000; double* pA = (double*) malloc(sizeof(double)*n); double* pB = (double*) malloc(sizeof(double)*n); double* pC = (double*) malloc(sizeof(double)*n); for(int i = 0; i < n; ++i) { pA[i] = (double) i; pB[i] = (double) i; pC[i] = (double) 0; } AddArrays(n, pA, pB, pC); AddArraysAmp(n, pA, pB, pC); free(pA); free(pB); free(pC); system("\npause"); } error C2228: выражение слева от ".data" должно представлять класс, структуру или объединение c:\program files\microsoft visual studio 11.0\vc\include\amp.h 2250 1 CpuGpu error C2228: выражение слева от ".data" должно представлять класс, структуру или объединение c:\program files\microsoft visual studio 11.0\vc\include\amp.h 2253 1 CpuGpu error C2338: container element type and array view element type must match c:\program files\microsoft visual studio 11.0\vc\include\amp.h 2253 1 CpuGpu error C2228: выражение слева от ".size" должно представлять класс, структуру или объединение c:\program files\microsoft visual studio 11.0\vc\include\amp.h 2255 1 CpuGpu Почему возникает эта ошибка в заголовочном файле Microsoft? Проект прикрепил Прикреплённый файлCpuGpuAmp.zip (2,25 Кбайт, скачиваний: 332) |
Сообщ.
#2
,
|
|
|
Скорее всего, где-то требуется std::vector, вместо указателя
Добавлено Либо какой-то из массивов apm Добавлено Цитата Олег М @ array_view<int, 1> a(n, pA); Здесь требуется обычный указатель, а ты передаёшь константный, она не может найти конструктор |
Сообщ.
#3
,
|
|
|
Попробовал исправить, убрал const, не удается скомпилировать код. Буду разбираться дальше.
|
Сообщ.
#4
,
|
|
|
Цитата tuchin @ Попробовал исправить, убрал const, не удается скомпилировать код. Буду разбираться дальше. Сделай вот так void AddArraysAmp(int n, const int *pA, const int *pB, const int *pC) |
Сообщ.
#5
,
|
|
|
Не помогло
|
Сообщ.
#6
,
|
|
|
Цитата tuchin @ Не помогло А как у тебя вообще передаются указатели на double в функцию, которая требует указатели на int? |
Сообщ.
#7
,
|
|
|
Пробовал и так:
void AddArraysAmp(int n, const double* const pA, const double* const pB, double* const pC) { clock_t start, finish, duration; start = clock(); array_view<double, 1> a(n, pA); array_view<double, 1> b(n, pB); array_view<double, 1> c(n, pC); parallel_for_each(c.extent, [=](index<1> idx) restrict(amp) { c[idx] = a[idx] + b[idx]; }); finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета C++ AMP" << endl; } int main() { setlocale(LC_ALL, ""); int n = 3; double* pA = (double*) malloc(sizeof(double)*n); double* pB = (double*) malloc(sizeof(double)*n); double* pC = (double*) malloc(sizeof(double)*n); for(int i = 0; i < n; ++i) { pA[i] = (double) i; pB[i] = (double) i; pC[i] = (double) 0; } AddArrays(n, pA, pB, pC); free(pA); free(pB); free(pC); system("\npause"); } Добавлено Кроме того, проверил результаты в Windows 10 и VS2015, результаты те же. При этом определить, что в коде примера не так у меня не получается, ошибку дает только amp.h. А разобраться в коде заголовочного файла Microsoft для меня непосильная задача. |
Сообщ.
#8
,
|
|
|
Тебе нужен, насколько я понимаю, чтобы вызывался вот этот конструктор array_view (что значит restrict, я не знаю)
array_view( int _E0, const _Value_type * _Src )restrict(amp,cpu); Т.е. const double *. А у тебя - const double* const. Поэтому компилятор выбирает другой. Сделай параметры const double *pA, ........ |
Сообщ.
#9
,
|
|
|
При int и double в функции
void AddArraysAmp(int n, const double* pA, const double* pB, double* pC) { clock_t start, finish, duration; start = clock(); //array_view<double, 1> a(n, pA); //array_view<double, 1> b(n, pB); //array_view<double, 1> c(n, pC); array_view<int, 1> a(n, pA); array_view<int, 1> b(n, pB); array_view<int, 1> c(n, pC); parallel_for_each(c.extent, [=](index<1> idx) restrict(amp) { c[idx] = a[idx] + b[idx]; }); finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета C++ AMP" << endl; } |
Сообщ.
#10
,
|
|
|
Цитата tuchin @ //array_view<double, 1> a(n, pA); //array_view<double, 1> b(n, pB); //array_view<double, 1> c(n, pC); Раскоментируй это, а то, что ниже убери |
Сообщ.
#11
,
|
|
|
void AddArraysAmp(int n, const double* pA, const double* pB, double* pC) { clock_t start, finish, duration; start = clock(); array_view<double, 1> a(n, pA); array_view<double, 1> b(n, pB); array_view<double, 1> c(n, pC); //array_view<int, 1> a(n, pA); //array_view<int, 1> b(n, pB); //array_view<int, 1> c(n, pC); parallel_for_each(c.extent, [=](index<1> idx) restrict(amp) { c[idx] = a[idx] + b[idx]; }); finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета C++ AMP" << endl; } |
Сообщ.
#12
,
|
|
|
Цитата tuchin @ array_view<double, 1> a(n, pA) А попробуй сделать array_view<const double, 1>, для a и b |
Сообщ.
#13
,
|
|
|
Ошибка (активно) выражение должно быть допустимым для изменения левосторонним значением CpuGpuVS2015 e:\MyProgramming\CpuGpuVS2015\CpuGpu.cpp 40
Ошибка C3892 Concurrency::array_view<const double,1>::operator []: невозможно присваивать значения переменной, которая объявлена как константа CpuGpuVS2015 e:\myprogramming\cpugpuvs2015\cpugpu.cpp 40 Другие ошибки исчезли |
Сообщ.
#14
,
|
|
|
Покажи код
|
Сообщ.
#15
,
|
|
|
Я забыл убрать const в array_view для c(n, pC). После исправления в программе
#include <string> #include <iostream> #include <Windows.h> #include <memory.h> #include <stdio.h> #include <time.h> #include <amp.h> using namespace std; using namespace concurrency; void AddArrays(int n, const double* const pA, const double* const pB, double* const pC) { clock_t start, finish, duration; start = clock(); for(int i = 0; i < n; ++i) { pC[i] = pA[i] + pB[i]; } finish = clock(); duration = finish - start; cout << duration << " - время расчета без OpenMP." << " Результат: " << pC[2] << endl; } void AddArraysAmp(int n, const double* pA, const double* pB, double* pC) { clock_t start, finish, duration; start = clock(); array_view<const double, 1> a(n, pA); array_view<const double, 1> b(n, pB); array_view<double, 1> c(n, pC); parallel_for_each(c.extent, [=](index<1> idx) restrict(amp) { c[idx] = a[idx] + b[idx]; }); finish = clock(); duration = finish - start; cout << duration << " pC[i] = pA[i] + pB[i]" << " Время расчета C++ AMP" << endl; } int main() { setlocale(LC_ALL, ""); int n = 16000; double* pA = (double*) malloc(sizeof(double)*n); double* pB = (double*) malloc(sizeof(double)*n); double* pC = (double*) malloc(sizeof(double)*n); for(int i = 0; i < n; ++i) { pA[i] = (double) i; pB[i] = (double) i; pC[i] = (double) 0; } AddArrays(n, pA, pB, pC); AddArraysAmp(n, pA, pB, pC); free(pA); free(pB); free(pC); system("\npause"); } Возникло необработанное исключение по адресу 0x751524F2 в CpuGpuVS2015.exe: исключение Microsoft C++: Concurrency::runtime_exception по адресу памяти 0x004FE81C. |
Сообщ.
#16
,
|
|
|
Тут уже мне сложно сказать, я с этой штукой тоже работать не умею.
На самом деле, эта задача легко решается с помощью обычных потоков. Примерно так #include <thread> #include <chrono> #include <iostream> static const size_t _sz = 1024 * 1024; static double a[_sz]; static double b[_sz]; static double c[_sz] = {0}; void CalcSum(size_t n, const double *a, const double *b, double *res) { //printf("%s, %lu\n", __FUNCTION__, n); for (size_t i = 0; i < 1000; ++i) { for (size_t i = 0; i < n; ++i) res[i] = sqrt(pow(a[i], 2) + pow(b[i], 2)); } } void TestCalc() { for (size_t i = 0; i < _sz; ++i) { a[i] = i; b[i] = i; } auto tm = std::chrono::steady_clock::now(); CalcSum(_sz, a, b, c); auto tm2 = std::chrono::steady_clock::now(); std::cout << "Time sync: " << std::chrono::duration_cast<std::chrono::milliseconds>(tm2 - tm).count() << std::endl; static const auto _procs = std::thread::hardware_concurrency(); std::cout << "Processors: " << _procs << std::endl; static const size_t _block = _sz / _procs; std::list<std::thread> threads; tm = std::chrono::steady_clock::now(); size_t offset = 0; for (size_t i = 0; i < _procs; ++i, offset += _block) threads.emplace_back(&CalcSum, _block, a + offset, b + offset, c + offset); if (offset < _sz) CalcSum(_sz - offset, a + offset, b + offset, c + offset); for (auto &thread: threads) thread.join(); tm2 = std::chrono::steady_clock::now(); std::cout << "Time async: " << std::chrono::duration_cast<std::chrono::milliseconds>(tm2 - tm).count() << std::endl; } |
Сообщ.
#17
,
|
|
|
Спасибо за код с потоками, он поможет при изучении потоков. А с этим примером даже не знаю, где можно проконсультироваться. Специализированных форумов я не нашел в интернете
|
Сообщ.
#18
,
|
|
|
Добрый день!
Дело в типе double. Прежде чем использовать этот тип, надо проверять, поддерживает ли его Ваша видеокарта. Это делается с использованием свойства supports_limited_double_precision у объекта accelerator – что-нить типа: accelerator defaultAccelerator; if (defaultAccelerator.supports_limited_double_precision) { … } Если не поддерживает, используйте float. |
Сообщ.
#19
,
|
|
|
Спасибо, Павел 77. Попробую.
|