Я пытаюсь создать бэкэнд для кроссплатформенного приложения, которое будет работать в Linux, iOS и Android.
Первоначально я создавал его с учетом iOS, поэтому использовал типы данных simd для моих float2 и моих матриц. Однако simd не доступен для Linux или Android, поэтому мне нужно что-то другое.
Конечно, я мог бы определить свой собственный тип матрицы и свои собственные типы float2 / 3/4, но я боюсь, что потеряю аппаратное ускорение ОСОБЕННО для умножения матриц.
Я попробовал посмотреть, смогу ли я создать структуры c ++, которые были бы эквивалентны типам simd, но вызывали всевозможные проблемы. Здесь были мои попытки.
struct float2 {
float x;
float y;
}; (Was supposed to be equal to simd_float2 and float2 in Metal shading language)
struct float3 {
float x;
float y;
float z;
}; (Was supposed to be equal to simd_float3 and float3 in Metal shading language)
struct float3x3 {
float columns[3][3];
}; (Was supposed to be equal to simd_float3x3 and matrix_float3x3 in Metal shading language)
struct Vertex {
float3 color;
float2 position;
}; (A struct that is supposed to be common between Engine and Metal Shading language however gets read COMPLETELY wrong when I try to do it this way)
// How can simd types possibly be defined in a way that these aren't equivalent
Когда я начал использовать эти структуры, весь хаос вырвался на свободу, и было ясно, что Металл не получил это.
Должен ли я на самом деле беспокоиться о производительности, связанной с использованием моих собственных определений и математики для умножения матриц?
Существуют ли какие-либо кроссплатформенные библиотеки, которые будут определять эти структуры как для приложения linux, так и для моего приложения Vulcan Android и моего приложения Metal iOS?
Вопрос (кроме вашего struct float3
не имеет 3 компонента), вероятно, из-за выравнивания. Например, как указано в Спецификация Metal Shading Language (MSL), MSL-х float3
(так же как simd
х) не размер 3 float
s, это размер 4. Структура, подобная этой:
struct float3 {
float x;
float y;
float z;
};
делает не соответствуют MSL float3
, это соответствует packed_float3
, Это особенно важно, если вы объединяете структуры данных, такие как создание массива struct float3
или создание структуры, содержащей поля типа struct float3
с другими полями после этого. Ваш struct Vertex
проявляет последнюю проблему. position
поле имеет неправильное смещение по сравнению с той же структурой в MSL.
Вы могли бы исправить свой struct float3
добавив четвертое поле, float padding;
, Вы также можете исправить это с помощью нестандартных расширений компилятора, таких как __attribute__ ((aligned(16)))
:
struct float3 {
float x;
float y;
float z;
} __attribute__ ((aligned(16)));
И GCC, и Clang поддерживают aligned
приписывать. Я уверен, что MSVC поддерживает аналогичную функцию, но я не помню, что это за руки.
Точно так же MSL float3x3
имеет размер 48 байтов и выровнен до 16 байтов. Это соответствует float3[3]
(при условии правильного определения float3
).
Других решений пока нет …