无法使用英特尔编译器强制内联C++函数
Can't force inlining C++ function using Intel compiler
我有一个函数定义为
inline void vec_add(__m512d &v3, const __m512d &v1, const __m512d &v2) {
v3 = _mm512_add_pd(v1, v2);
}
(__m512d
是一个本地数据类型映射到Intel MIC架构上的SIMD寄存器)
由于此函数相当短且经常被调用,因此我希望在每次调用时都将其内联。但是英特尔的编译器似乎不愿意内联这个函数,即使在我使用-inline-forceinline
和-O3
选项之后。它报告说,"Forceinline未被调用……",同时编译。由于我必须使用一些编译器特定的功能,例如__m512d
类型,英特尔编译器是我唯一的选择。
更多信息:
文件结构非常简单。函数vec_add
定义在头文件mic.h
中,该头文件包含在另一个文件test.cc
中。函数vec_add
只是在循环中重复调用,不涉及函数指针。test.cc
中简化版的代码如下所示
for (int i = 0; i < LENGTH; i += 8) {
// a, b, c are arrays of doubles, and each SIMD register can hold 8 doubles
__mm512d va = _mm512_load_pd(a + i); // load SIMD register from memory
__mm512d vb = _mm512_load_pd(b + i); // ditto
__mm512d vc;
vec_add(vc, va, vb); // store SIMD register to memory
_mm512_store_pd(c + i, vc);
}
我尝试了各种提示,如__attribute__((always_inline))
, __forceinline
和编译器选项-inline-forceinline
,但没有一个有效。
完整代码
我把所有相关的代码以简化的形式放在一起。如果你有英特尔编译器,你可以尝试一下。使用-Winline
选项查看内联报表,使用-inline-forceinline
选项强制内联。
#include <stdio.h>
#include <stdlib.h>
#include <immintrin.h>
#define LEN (1<<20)
__attribute((target(mic)))
inline void vec_add(__m512d &v3, const __m512d &v1, const __m512d &v2) {
v3 = _mm512_add_pd(v1, v2);
}
int main() {
#pragma offload target(mic)
{
double *a = (double*)_mm_malloc(LEN*sizeof(double), 64);
double *b = (double*)_mm_malloc(LEN*sizeof(double), 64);
double *c = (double*)_mm_malloc(LEN*sizeof(double), 64);
for (int i = 0; i < LEN; i++) {
a[i] = (double)rand()/RAND_MAX;
b[i] = (double)rand()/RAND_MAX;
}
for (int i = 0; i < LEN; i += 8) {
__m512d va = _mm512_load_pd(a + i);
__m512d vb = _mm512_load_pd(b + i);
__m512d vc;
vec_add(vc, va, vb);
_mm512_store_pd(c + i, vc);
}
_mm_free(a);
_mm_free(b);
_mm_free(c);
}
}
<<p> 配置/strong> - 编译器:Intel Compiler (ICC) 14.0.2 编译选项:
-O3 -inline-forceinline -Winline
你知道为什么这个函数不能内联吗?我怎么才能让它内联毕竟(我不想转向宏)?
由于某种原因,英特尔编译器在卸载代码中不做函数内联(我不太熟悉这个概念,所以我不知道这是什么技术原因)。参见effective-use-of- intel-compiler -offload-features获取更多信息(只需搜索"inline")。
引用链接文章:
函数内联到卸载结构
有时候,内联函数对于实现最佳性能是必要的生成的代码。在#pragma offload中直接调用的函数不被编译器内联,即使它们被标记为内联。来在卸载区域启用代码的最佳性能,或者手动启用内联函数,或者将整个卸载构造放到自己的结构中函数。
…
一个解决方案是手动内联函数f,如function所示v2。
另一个解决方案是将卸载构造移到它自己的构造中函数如函数v3所示。
如果我理解正确的话,最好的方法是将循环放入一个单独的函数中,该函数也标记为__attribute((target(mic)))。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗