将SSE矩阵矢量乘法代码转换为AVX
Convert SSE matrix-vector multiplication code to AVX
我正在尝试将SSE函数转换为AVX。这个函数做向量矩阵乘法,这是我的SSE代码:
void multiply_matrix_by_vector_SSE(float* m, float* v, float* result, unsigned const int vector_dims)
{
size_t i, j;
for (i = 0; i < vector_dims; ++i)
{
__m128 acc = _mm_setzero_ps();
for (j = 0; j < vector_dims; j += 4)
{
__m128 vec = _mm_load_ps(&v[j]);
__m128 mat = _mm_load_ps(&m[j + vector_dims * i]);
//acc = _mm_add_ps(acc, _mm_mul_ps(mat, vec));
acc = _mm_fmadd_ps(mat, vec, acc);
}
acc = _mm_hadd_ps(acc, acc);
acc = _mm_hadd_ps(acc, acc);
_mm_store_ss(&result[i], acc);
}
}
以下是我对AVX的看法:
void multiply_matrix_by_vector_AVX(float* m, float* v, float* result, unsigned const int vector_dims)
{
size_t i, j;
for (i = 0; i < vector_dims; ++i)
{
__m256 acc = _mm256_setzero_ps();
for (j = 0; j < vector_dims; j += 8)
{
__m256 vec = _mm256_load_ps(&v[j]);
__m256 mat = _mm256_load_ps(&m[j + vector_dims * i]);
acc = _mm256_fmadd_ps(mat, vec, acc);
}
acc = _mm256_hadd_ps(acc, acc);
acc = _mm256_hadd_ps(acc, acc);
acc = _mm256_hadd_ps(acc, acc);
acc = _mm256_hadd_ps(acc, acc);
_mm256_store_ps(&result[i], acc);
}
}
但是AVX代码崩溃(Access violation reading location 0xFFFFFFFFFFFFFFFF
)。
有人能帮我使我的AVX功能正常工作吗?
PS:我在函数中传递的矩阵和向量的大小总是8的倍数。此外,我传递给SSE函数的数组是16位对齐的(__declspec(align(16))float* = generate_matrix(256);
),而我传递给AVX函数的数组则是32位对齐(__declspec(align(32))float* = generate_matrix(256);
);
不幸的是,使用这样的水平加法并不能简单地扩展到256位,因为指令(以及大多数其他指令)是"laned"的——它的作用就像两个并行的haddps
,一个在上半部分,一个位于下半部分,没有混合,所以下半部分和上半部分不会相加。
当然,这仍然不是一个压缩的结果,并且该压缩的存储中有一个对齐的存储写入某个未对齐的地址,并且将失败(这个错误有点奇怪,但不管怎样)。
无论如何,让我们修复水平总和:(未测试)
// this part still works
acc = _mm256_hadd_ps(acc, acc);
acc = _mm256_hadd_ps(acc, acc);
// this is new
__m128 acc1 = _mm256_extractf128_ps(acc, 0);
__m128 acc2 = _mm256_extractf128_ps(acc, 1);
acc1 = _mm_add_ss(acc1, acc2);
// do scalar store, obviously
_mm_store_ss(&result[i], acc1);
顺便说一句,内环需要10个独立的链(和10个累加器)才能最大限度地提高Haswell的吞吐量。
相关文章:
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 如何将 c++ get 函数代码转换为 opencv 算法中使用的 python
- 将 OpenCV 2 中的ANN_MLP代码转换为 OpenCV 3 代码
- 将 c++ 代码转换为 python,使用运算符?
- 使用 jni 将返回带有模板的对象的 Java 代码转换为 c++
- 如何在 Poco 中将工作 HTTP 代码转换为 HTTPS
- 将C++代码转换为 R 代码以生成数据
- 如何将C++ lambda 函数代码转换为 C#?
- 将 python、numpy 和 scipy 代码转换为兼容C++代码?
- 将本机C 代码转换为Java
- 将C++非托管代码转换为 C#
- 将Qt的QML代码转换为C++
- 将此C 代码转换为MIPS
- 如何将此代码转换为两个以上的数字(计算HCF)
- 想要将此 Matlab 代码转换为 OpenCV 代码
- 尝试将 C++11 代码转换为 C++03 时默认函数模板参数出错
- 将阻止同步代码转换为异步
- 将视觉C 代码转换为Borland C 构建器
- 如何将VDT的Pade Exp fast_ex()的双重版本的标量代码转换为SSE2?
- 将 ML 代码转换为 C++