Каков наилучший способ загрузки из константного указателя с использованием altivec?
Согласно документации (и моим результатам) vec_ld не принимает указатель const в качестве аргумента:
http://www-01.ibm.com/support/knowledgecenter/SS2LWA_12.1.0/com.ibm.xlcpp121.bg.doc/compiler_ref/vec_ld.html
Следовательно, что-то вроде этого не получится:
void foo(const float* A){
vector4double a = vec_ld(0,A);
...
}
Гадкий обходной путь будет:
void foo(const float* A){
vector4double a = vec_ld(0,const_cast<float*>A);
...
}
Есть лучший способ сделать это?
Спасибо.
использование const_cast
,
Он существует именно для этой цели: обработка константно-некорректных API.
Функция vec_ld загружает 128-битный вектор (4 значения с плавающей запятой) в регистр Altivec. Загрузка выполняется с 16-байтового выровненного адреса. Он не работает должным образом, если адрес не имеет 16-байтового выравнивания. В этом случае вы должны использовать следующую функцию:
typedef __vector uint8_t v128_u8;
typedef __vector float v128_f32;
inline v128_f32 Load(const float * p)
{
v128_u8 lo = vec_ld(0, p);
v128_u8 hi = vec_ld(A, p);
return (v128_f32)vec_perm(lo, hi, vec_lvsl(0, p));
}
или используйте функцию vec_vsx_ld, если у вас есть процессор Power7 или Power8.
Ваш const float *
означает, что вы указываете на что-то, что нельзя изменить, но вы все еще можете указать на что-то еще.
Я не знаю о твоей функции vec_ld
но я предполагаю, что, поскольку он требует указателя на число с плавающей точкой, функция изменит указанное значение.
Затем вы должны указать изменяемое значение.
Я бы не стал использовать ваш мерзкий обходной путь, потому что пользователь, вызывающий ваш метод, не будет ожидать, что его значение с плавающей запятой будет изменено, и это наверняка будет причиной неприятной ошибки в будущем.
Если бы вы могли изменить свой метод foo
в foo(float * A)
или же foo(float & A)
это было бы облегчением.
Для получения дополнительной информации о константном указателе см .: В чем разница между const int *, const int * const и int const *?