我正在尝试利用新的AVX2 GATHER指令来加速稀疏矩阵 - 向量乘法.矩阵采用CSR(或耶鲁)格式,行指针指向列索引数组,而列索引数组又保存列.这样一个mat-vec mul的C代码看起来像这样:
for (int row = 0; row < n_rows - 1; row++) {
double rowsum = 0;
for (int col = row_ptr[row]; col < row_ptr[row + 1]; col++) {
rowsum += values[col] * x[col_indices[col]];
}
result[row] = rowsum;
}
Run Code Online (Sandbox Code Playgroud)
现在我的目标是通过AVX2内在函数加速这一点.以下代码适用于最新的英特尔或GCC,基于https://blog.fox-toolkit.org/?p=174.我删除了剩余部分,因为我的行都在4个双打(列%4 == 0)上对齐(幸运的是我).如果有人感兴趣,我也有处理余数的代码,但关键是,代码实际上稍慢.我检查了反汇编,对于上面的版本,只生成FP指令,对于我的AVX2代码,所有AVX2操作都按预期显示.即使使用适合缓存的小矩阵,AVX2版本也不行.我在这里很困惑......
double* value_base = &values[0];
double* x_base = &x[0];
int* index_base = &col_indices[0];
for (int row = 0; row < n_rows - 1; row++) {
int col_length = row_ptr[row + 1] - row_ptr[row]; …Run Code Online (Sandbox Code Playgroud) 我对以下代码的行为/输出感到困惑,要么这是一个错误,要么我遗漏了一些东西。(天湖拱门上的 Ubuntu 16.04)
#include <iostream>
int wrap(unsigned long long val) {
return __builtin_clzll(val);
}
using namespace std;
int main() {
cout << __builtin_clzll(0) << " " << wrap(0) << endl;
cout << __builtin_clzll(1) << " " << wrap(1) << endl;
cout << __builtin_clzll(2) << " " << wrap(2) << endl;
}
Run Code Online (Sandbox Code Playgroud)
这是不同编译设置下的不同输出。我知道如果传递零, clz 可能会返回未定义的结果。然而,直接内联调用总是可以正常工作,但是一旦涉及到堆栈,编译器就会搞砸。
snk@maggy:~/HCS$ g++ -O0 test.cpp -o test
snk@maggy:~/HCS$ ./test
64 4196502
63 63
62 62
snk@maggy:~/HCS$
Run Code Online (Sandbox Code Playgroud)
-O > 0 级别不会改变结果,我猜 gcc 是内联的。这是预期的结果……
snk@maggy:~/HCS$ g++ -O1 test.cpp -o …Run Code Online (Sandbox Code Playgroud)