Я хотел бы использовать векторное расширение RISC-V в своем приложении на C++. Я заметил, что для членов класса невозможно использовать типы RVV (например, «vuint32m1_t»). При компиляции с помощью gcc (v13.2.0) я получаю следующую ошибку:
error: member variables cannot have RVV type 'vuint32m1_t'
Я не смог найти ссылки в Интернете.
Я думаю, что решением может быть использование стандартных типов (например, uint32_t) для членов класса и преобразование их в типы RVV всякий раз, когда мне нужно выполнить векторную операцию. Я считаю, что это решение может снизить производительность.
У кого-нибудь есть другие идеи?
Векторные регистры RVV не зависят от длины вектора, и вы не знаете длину вектора во время компиляции. Вы не можете поместить векторные типы RVV непосредственно в классы, поскольку размер класса и структуры должен быть известен во время компиляции.
Обычно вам не нужно хранить векторы в классах, вместо этого вы сохраняете данные и загружаете их при необходимости. В противном случае вы могли бы выделить достаточно места для вектора, запрашивая длину вектора во время выполнения. Оба эти метода проблематичны, если вам нужно часто загружать в хранилище одни и те же данные, поскольку gcc и clang еще не могут выполнить исключение хранилища с предикатной векторной загрузкой.
Если вы нацелены на определенную длину вектора и только на эту конкретную длину вектора, вы можете использовать атрибут riscv_rvv_vector_bits, который можно размещать внутри структур и классов. Пожалуйста, не используйте это, если можете этого избежать, это делает ваш код непереносимым.
Действительно ли вам нужно поместить векторы непосредственно в класс для решения вашей задачи?
Часто можно изменить API, чтобы он не был нужен, например. forEach
функция обратного вызова вместо API-итератора, но иногда вы не можете изменить API.
Я пытаюсь собрать случаи, когда вам действительно нужна эта функция, потому что есть решение, которое дает вам 95% результатов, но его не так-то просто реализовать. Компиляция может предоставить тип с фиксированным размером 512 бит и сгенерировать код таким образом, что, когда длина вашего вектора меньше, вы просто получаете доступ к младшим битам, а когда длина вашего вектора больше, вы не используете дополнительные кусочки ваших векторов. Это дает вам код, полностью независимый от длины вектора, который масштабируется от VLEN=128 до VLEN=512. Он также будет работать на VLEN>512, хотя и без полного использования возможностей вашего оборудования.
Спасибо за ваш ответ. Я полностью согласен, что это нестандартный способ использования RVV. Однако мне нужно портировать код SSE2, в котором есть член класса типа __m128i. В этом классе много векторных операций, а отсутствие члена класса типа RVV заставляет меня очень часто загружать и сохранять вектор.
Что, если вы просто используете стандартные типы и позволяете компилятору (с включенной оптимизацией) заботиться об оптимизации кода?