OpenCL 128-битный результат умножения
Мне нужно умножить два беззнаковых 64-битных целых числа (без знака long) внутри ядра OpenCL, в результате получим 128-битное целое число (без знака long long).
Более новые версии openCL, кажется, поддерживают этот тип.
unsigned long m1, m2;
.
.
unsigned long long result = m1 * (unsigned long long)m2;
Этот код работает, но довольно медленно. Это по сути умножение 64 бит на 128 бит. Мне нужно только 64 бит с 64 бит.
Есть ли способ установить тип результата умножения без преобразования одного умножителя в 128 бит?
1 ответ
Приличный компилятор должен заметить вашу 64->128-битную передачу и не производить никакого машинного кода для обнуленных старших битов.
Тем не менее, графические процессоры имеют тенденцию быть довольно медленными при умножении большого целого числа. Например, согласно последней информации, которую я знаю, графические процессоры AMD GCN в 5 раз быстрее при умножении чисел с плавающей запятой, чем 32 * 32-битные целые числа. Я подозреваю, что это только с 32-битным (младшим) результатом, поскольку получение старших 32-битных данных - это отдельная инструкция, поэтому, возможно, даже медленнее для полного 64-битного результата.
В наши дни большинство графических процессоров намного быстрее работают с 24-битными целыми числами. (В 5 раз быстрее в случае вышеупомянутых графических процессоров AMD.) Интересно, сможете ли вы разложить ваши 64-битные целые на 3 24-битных слова (или даже на 2, если ваши значения уместятся в 48 бит)? длинное умножение вручную. (Возможно, с помощью алгоритмов Карацубы или подобных алгоритмов; не уверен, что будет работать лучше всего, так как mul, add и mad имеют тенденцию быть одинаково быстрыми по сравнению друг с другом на графических процессорах.) Хотя получение высоких 16 бит каждого умножения 24x24 бит будет сложной задачей, хотя Так как OpenCL не предоставляет вам доступ к нему через выделенную функцию, в отличие от младших 32 бит через mul24. Если вы ориентируетесь на одну или несколько конкретных реализаций OpenCL, возможно, будет возможно написать язык ассемблера для GPU, на который вы ориентируетесь.