Проблемы выравнивания памяти с векторным расширением GCCC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Проблемы выравнивания памяти с векторным расширением GCC

Сообщение Anonymous »

Я пытаюсь использовать векторное расширение GCC (https://gcc.gnu.org/onlinedocs/gcc/Vect ... sions.html), чтобы ускорить умножение матриц. Идея состоит в том, чтобы использовать инструкции SIMD для умножения и сложения четырех чисел с плавающей запятой одновременно. Минимальный рабочий пример приведен ниже. Пример отлично работает при умножении матрицы (M=10,K=12) на матрицу (K=12,N=12). Однако когда я меняю параметры (скажем, N=9), я получаю ошибку сегментации.
Я подозреваю, что это связано с проблемами выравнивания памяти. Насколько я понимаю, при использовании SIMD для вектора с 16 байтами (в данном случае float4) адрес целевой памяти должен быть кратен 16. Уже обсуждаются проблемы выравнивания памяти с инструкциями SIMD. (например, связь между векторизацией SSE и выравниванием памяти). В приведенном ниже примере, когда &b(0,0) равно 0x810e10, &b(1,0) равно 0x810e34, что не кратно 16.
Мои вопросы:
  • Правда ли, что я получаю ошибку из-за проблем с выравниванием памяти?
  • Может ли кто-нибудь сказать мне, как исправить проблема легко? Я думал использовать двумерный массив вместо одного массива, но не хочу этого делать, чтобы не менять остальные коды.
Минимальный рабочий пример
#include
#include
#include
#include
#include
#include
using namespace std;
typedef float float4 __attribute__((vector_size (16)));

static inline void * alloc64(size_t sz) {
void * a = 0;
if (posix_memalign(&a, 64, sz) != 0) {
perror("posix_memalign");
exit(1);
}
return a;
}

struct Mat {
size_t m,n;
float * a;
Mat(size_t m_, size_t n_, float f) {
m = m_;
n = n_;
a = (float*) malloc(sizeof(float) * m * n);
fill(a,a + m * n,f);
}
/* a(i,j) */
float& operator()(long i, long j) {
return a[i * n + j];
}
};

Mat operator* (Mat a, Mat b) {
Mat c(a.m, b.n,0);
assert(a.n == b.m);
for (long i = 0; i < a.m; i++) {
for(long k = 0; k < a.n; k++){
float aa = a(i,k);
float4 a4 = {aa,aa,aa,aa};
long j;
for (j = 0; j

Подробнее здесь: https://stackoverflow.com/questions/417 ... -extension
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»