|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
||||||||||||||||||||||||||||||||||||
Непредсказуемые изменения точности расчётов внутри kernel10.04.2024, 00:29. Показов 3710. Ответов 45
Метки нет (Все метки)
Всем доброго времени суток!
Не так много времени прошло, но я снова вынужден обратиться за помощью к сообществу. Не по теме: Ну, тут правда то ли я тупой, то ли лыжи не едут. Я ДВА ДНЯ потратил на отладку, чтобы узнать, что проблема ни разу не в моих алгоритмах - просто OpenCL'ю иногда хочется посчитать 9 знаков после запятой, а не 15. Прошу прощения. Смотрите, есть простая программа по вычислению длины отрезка дуги на поверхности сферы:
Поясняю. Вот код управляющей программы (Qt 5, CUDA 12.4, OpenCL 3.0 (auto)): Кликните здесь для просмотра всего текста
и код файла CalcDist.cl: Кликните здесь для просмотра всего текста
Если просто запустить эту программу и сравнить значения дистанции, то мы увидим
Главная причина этого в том, что значение переменной p2 оказывается таким:
Однако, если мы после основного расчёта (внутри kernel) дистанции продублируем его, разделив расчёт переменной p2 на три отдельных операции, то, О ЧУДО, вывод окажется следующим:
Не по теме: Какие-то приколы из мира Arduino, чесслово Я думал, что нашёл проблему, и заменил старые одношаговые секции кода новыми - многошаговыми. КАК же я был удивлён, когда на выходе снова получил восемь несчастных корректных знаков после запятой из 15. Отсюда и сам мой вопрос - а что, собственно, происходит? Почему, я даже не знаю, как это правильно назвать, видеокарта не хочет с первого раза нормально считать? Почему корректный расчёт происходит только при избыточном дублировании? На всякий случай, прикладываю полный консольный вывод приведённой выше программы:
Не по теме: За помощь с перевоспитанием сумасбродной видеокарты, судя по всему
0
|
||||||||||||||||||||||||||||||||||||
| 10.04.2024, 00:29 | |
|
Ответы с готовыми решениями:
45
Повышение точности расчетов Повышение точности расчетов в Matlab Уменьшение точности расчетов (округление) |
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|||||||||||||||
| 19.04.2024, 01:10 [ТС] | |||||||||||||||
![]() Как строится расчёт синуса для точности float (если не CORDIC)? Через интервальные аппроксимации параболами (см. рисунок). Например, точность float (ошибка <1.0E-08) обеспечивается всего лишь ~150 интервалами (если разбиваем от 0 до pi/2), при этом, точности 1.0E-12 достигнуть не удаётся и при числе интервалов в 5000. Более того - точность не растёт при увеличении числа интервалов свыше 3000, а падает. Очевидно, что точности double таким образом достичь не удастся.Для сходящихся функций (синус, косинус) прекрасно работает ряд Тейлора. Точно так же делим участок [0, pi/2] на N интервалов и раскладываем функцию синуса в ряд Тейлора в точке центра каждого интервала, после чего записываем коэффициенты получившегося полинома (с заранее заданной степенью i[SUB]max[/SUB]) в таблицу:
<3.0E-16 (по данным MatLab) на 125 интервалах с полиномом 6 степени.Отдельно стоит сказать о том, как я нахожу в таблице нужные коэффициенты полинома. Поскольку участок равномерно разбит на N интервалов, можно использовать простую линейную функцию вида y = k*x, где y - номер интервала, а x - аргумент функции sin(x). Отмечу, однако, что мой "бенчмарк" C++ сказал мне, что "MatLab не прав", и выдал максимальную ошибку в 1.2E-14, что, в целом, меня устроило.С тангенсом я не стал разбираться и бахнул tan(x) = sin(x) / cos(x). Дорого, но я использую эту функцию довольно редко.Функции же арксинуса и арккосинуса расходятся, поэтому Тейлор тут мдееееее.. Да тут, как оказалось, что угодно будет мдееееее. Оказывается, арк-функции вычисляют через арктангенс, который сходится по формулам, использующим корень. Но разложить функцию арктангенса через ряд Тейлора, как я понял, невозможно, поэтому пользуются другими "аппроксиматорами". Я решил использовать аппроксимацию Паде: степень полинома числителя - 3, знаменателя - 5, число интервалов - 159. Эта функцию определена для любого x, кроме inf и NaN (нужно для inf - бахайте туда x=квинтиллион). Порядок точности получился тем же, что и для синуса с косинусом. Оговорки есть только с интервальным разбиением - здесь не одно равномерное разбиение, а три (x: 0-10, 10-20, 20-40) и пять определённых вручную "широких" интервалов, неравномерно уходящих в "бесконечность".Ссылок нет, поскольку когда я это всё делал, большей теорией, чем та, что я сейчас написал, я не обладал. Неделя экспериментов, и программная реализация тригонометрии для double готова. В шейдеры, кстати, я загружал таблицы через SSBO; хотел захардкодить, но компилятор оПтИмИзИрУеТ константы, если они кажется ему слишком большими. Ох уж эти 10 Кб информации. Не по теме: Кстати я также реализовал CORDIC для double в шейдерах (только для синуса). Работало это чудо в 11 (ужасть) раз медленнее, чем моя "табличная" тригонометрия. Я не ожидал, что операции смещения битов в целых числах дороже, чем возведения в степень, умножения и сложения.
1
|
|||||||||||||||
|
|
||||
| 19.04.2024, 01:31 | ||||
|
Продолжаю эксперименты с точностью)
Получаю интересные результаты, если коротко: зря мы гоним на точность OpenCL, или, брать результат работы NativeCPU код за эталон - так себе идея ![]() У меня есть ф-ия, которая генерит вершины спирали на поверхности сферы. Когда я увеличил количество вершин за оборот до 36000, то есть вершины генерятся с шагом в 0,01 градус и начало спирали (первая вершина) в центре(на нулевом расстоянии) то увидел следующее:
Видно, что CPU рапартует нам о нулевом расстоянии, тогда как разница между координатами точек точно не нулевая (от 1e-7 до 1e-10) Тогда я решил распечать первые 10 расстояний посчитаных на CPU:
Кликните здесь для просмотра всего текста
Короче, можно смело резать долготу < 1.25E-9 и широту < 1.0e-6 ![]() Но это тоже не сильно поможет так как напимер distCPU 6,7,8 абсолютно идентичны, тогда как на OpenCL - нет
1
|
||||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|||
| 19.04.2024, 15:07 [ТС] | |||
C++. Чтобы её проверить и отладить, я составил несколько тестовых наборов данных и вручную рассчитал результаты для каждого из них (ну, как вручную - с помощью систем символьной математики), чтобы точно понимать, что, где и как должно "идти" в любой момент времени.Как обычно, чуда не произошло и на этот раз, и моя C++-реализация обрабатывает тестовые наборы не только правильно, но и с той же точностью на каждом шаге, какую дала символьная математика (1e-16).Именно поэтому, по крайней мере, в рамках данной проблемы, я и принимаю результаты, получаемые на CPU, за эталон, с которым и сравниваю данные, идущие с GPU. Да и давайте честно - библиотеке <math.h> сто лет в обед; не доверять ей - не доверять ничему.Далее. Как я уже говорил, вычислительный шейдер OpenGL (4.3) выдаёт мне те же данные, что и CPU с оговоркой на точность моей переопределённой тригонометрии. Но OpenCL настолько далеко даже от вычислительного шейдера (спецификация к которому не менялась с 2014 года), что я уверен, что дело в OpenCL. Возможно, дело в OpenCL 3.0, который у меня выставляется автоматически, но я пока не понял, как указать программе конкретную версию. Возможно, это просто ошибка в драйверах, но даже на примере вашего .exeшника мы видим неадекватное снижение точности даже по сравнению с GPU-собратом RX6800XT. Опять же, упомяну, что если я ставлю float в OpenGL, то точности не хватает только при определённых входных данных, а если в OpenCL - оно в принципе считает неверно. Разобраться бы со скачками точности, а там и ограничить можно.
0
|
|||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
||
| 19.04.2024, 17:20 | ||
|
З.Ы. и там еще такой нюанс, что математический сопроцессор в CPU считает точнее чем double, там 19-20 десятичных знаков. Потом при записи в память результат округляется до 15-16 знаков. А видяха если и поддерживает double то в точности по стандарту 15-16 знаков. В общем, я бы все таки поставил драйвер OpenCL для процессора и подсунул ему девайс-ЦПУ. Велика вероятность, что дело не в OpenCL, а в видеокарте, тем более, что это Nvidia, там дядюшка Хуанг "срезает углы" где только можно.
1
|
||
|
|
|||
| 19.04.2024, 17:40 | |||
|
потому как у меня CPU возвращает одинаковое расстояние 0.0000949369370937348 км
1
|
|||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|||||||||||||||||||||||||||
| 20.04.2024, 01:49 [ТС] | |||||||||||||||||||||||||||
Табличка (все расстояния приведены к метрам)
Теперь о главном - первый замер показывает, что вычислительный шейдер справился в десять раз лучше со своей работой. Отключение же оптимизаций не помогло OpenCL'ю перестать врать и никак не приблизило его даже к уровню шейдера (как я и говорил - столь же неправильные, но другие, значения). Второй замер оказался интереснее (перепроверено дважды). Вычислительный шейдер снова сильно обходит OpenCL-реализацию, однако лишь до тех пор, пока не ставишь флаг отключения оптимизаций - с флагом совпадают 19 (!все!) знаков, что, помятуя о точности double, определяемой 16 знаками максимум, говорит нам о том, что видеокарта применила точно такой же механизм, что применил процессор (ведь абсолютно одинаковый мусор с 17 по 19 знаки может идти только в этом случае).И вот об этом "красивом" случае я и говорю - если вычислительный шейдер ведёт себя последовательно, выдавая мне "9.5" правильных знаков из 16, то kernel делает, что захочет - на одних входных данных на тебе 8 точных знаков, и ничего ты с этим не поделаешь, а на других - на тебе 9 знаков, но если отключишь оптимизацию, то, так уж и быть, посчитаю точно. А почему для первого набора ты не хочешь считать точно с отключенной оптимизацией? Принцип "хочу / не хочу"? Ну, компьютеры не так работают (вроде бы). Драйверы NVidia шалят, или в OpenCL 3.0 напортачили?Не по теме: Меня, как программиста-учёного, глубоко расстраивают ситуации, в которых ты, даже используя дорогущие профессиональные решения (OpenCL 3.0.15 + CUDA 12.4 + RTX4080), не имеешь физической возможности собрать программу так, чтобы она работала правильно. Конечно, не исключаю, что именно игровые драйверы RTX4080 вносят неоценимый вклад во все мои проблемы. Как бы то ни было, в скорейшем времени я запущу тестовую программу на A100, и мы сможем узнать больше о виновниках торжества. <math.h>'овской и не может являться причиной бед. Поэтому я не вижу особого смысла в тесте моей тригонометрии - она объективно хуже, хотя компилятор, действительно, может прийти в заблуждение и перестать оптимизировать тригонометрию (если он это делает). Может, попробую после тестов на A100.cl::program::build(). Есть очень старые инструменты компиляции OpenCL-кода в PTX-формат, но они не развиваются со времён OpenCL 1.2.
1
|
|||||||||||||||||||||||||||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
|||
| 20.04.2024, 17:10 | |||
|
Добавлено через 1 час 7 минут может отключение флага оптимизации вообще приводит к тому что расчет идет на процессоре? потому то и совпадают все 19 знаков, иначе такого просто физически не может быть
1
|
|||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
||||
| 20.04.2024, 18:38 [ТС] | ||||
<std::chrono> выводит наносекундную разницу, и верить этому, или нет - я не знаю). Моя большая программа, однако, при входных данных, не вызывающих сбоев, показывает разницу втрое. Но я не исследовал вопрос по-нормальному.x64 эмулируются, то что мешает производителю эмулировать и x87?
0
|
||||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
|||
| 20.04.2024, 19:29 | |||
|
сильно сомневаюсь
0
|
|||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|||||||||||||
| 20.04.2024, 22:20 [ТС] | |||||||||||||
![]() Что я делаю в коде:
0, я получаю падение программы, да и не удивительно - ведь она видит лишь одно пригодное устройство.Поэтому я не сомневаюсь, что расчёт идёт исключительно на GPU. Да и колонка №1 в таблице говорит о том, что даже с -cl-opt-disable регулярно идут бредовые данные, то есть, на CPU программа не переходит.
0
|
|||||||||||||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
||
| 20.04.2024, 23:56 | ||
|
Теперь в списке 3 девайса - видеокарта и два процессора, при том что эти процессоры считают по разному, как писал выше.
0
|
||
|
|
||
| 22.04.2024, 14:56 | ||
|
или винда для цп-intel сама ставит эксклюзивно (хотя когда у меня был i7-6700K тоже ничего не было без драйвера), но для амд без установки драйвера процессор не участвует точно. Ромуальд_7, короче я не знаю как у вас такая точность получается... я уже и векторную форму проверил и в ТГ-группе Delphi/Lazarus спросил везде +/- одно и тоже и получается что не более 0,5 метра точность (5e-4 км на около нулевых расстояний), не важно где считать (CPU/OpenCL), да там и считать особо нечего: два синуса, три косинуса и арккосинус. А в векторной форме вообще 3 умножения и арккосинус, думаю, это самый быстрый способ, хотя это надо ещё проверить... Может позже сделаю бенч, только на Delphi перенесу, чтобы компилятор был другой, на всякий случай.
1
|
||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|
| 22.04.2024, 19:56 [ТС] | |
|
snake32, Ну, тут уж что уж
![]() В любом случае, спасибо!
0
|
|
|
|
||
| 23.04.2024, 10:11 | ||
![]() Ромуальд_7, а у вас случайно не 32-битный режим? В 32-битном обычно для вычислений используется сопроцессор x87, где есть режим вычислений 10-байт (extended), а в x64 - максимум только векторные 8-байтные регистры (double)
0
|
||
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|
| 23.04.2024, 10:16 [ТС] | |
|
snake32, нене, точно не 32-битный. Да а даже и если так, что бы изменилось? (Просто интересно)
А хотя, вот как работает метод .build()? Как он, опять же, компилирует?
0
|
|
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
|
| 23.04.2024, 12:00 | |
|
Ромуальд_7, это то что я писал, сопроцессор x87 считает (внутри себя, т.е. если нет промежуточных сохранений) с точностью Extended (80-bit), а x64 это на расширениях AVX, SSE - тут только 64 bit.
0
|
|
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
||
| 23.04.2024, 12:46 [ТС] | ||
![]() Вопрос-то главный в том, что компилятор kernel'а делает, а не что я указываю для gcc.
0
|
||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
|
| 23.04.2024, 13:01 | |
|
Ромуальд_7, так kernel компилирует драйвер, а gcc это код "обвязки", так же как с вычислительным шейдером.
0
|
|
|
194 / 29 / 5
Регистрация: 11.04.2015
Сообщений: 735
|
|||||||
| 23.04.2024, 13:11 [ТС] | |||||||
|
Смотрите, в спецификации есть часть:
nvcc, вроде вышеупомянутого --fmad=false, но когда я передаю параметр через -D он просто игнорируется. Я не понял, что такое IL, но, похоже, ядро компилируется именно через него.
0
|
|||||||
|
827 / 244 / 47
Регистрация: 24.01.2013
Сообщений: 750
|
|
| 23.04.2024, 13:20 | |
|
Ромуальд_7, с этим не могу помочь, не разбирался с этими параметрами, увы.
Добавлено через 4 минуты там препроцессор для kernel'а свой, отдельный от С++. Может есть возможность в самом kernel'е задать дефайн?
0
|
|
| 23.04.2024, 13:20 | |
|
Построить график изменения вероятности нахождения в состояниях со временем (по результатам расчетов)
Непредсказуемые синие экраны Stripos - непредсказуемые результаты Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
|
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
|
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701
Купил два термопринтера QR701.
На сэлф-тесте написано:
Language: PC936 (GB18030).
Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
|
|
Создание формы заимствованного документа
Maks 03.08.2026
Задача:
Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также
табличная часть со следующими реквизитами:
- Расчетный счет покупателя. . .
|
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача:
В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
|
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов.
Логика кажется понятной:
1. Находим ключевые слова.
2. Добавляем их на. . .
|
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302
Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
|