OpenMP支持的编程语言:C、C++和Fortran;支持OpenMp的编译器包括Visual studio,Sun Compiler,GNU Compiler和Intel Compiler, Clang。具体见:https://www.openmp.org/resources/openmp-compilers-tools/
OpenMP功能中最强大的一个功能:在串行程序的源码基础上,只要进行少量的改动,就可以并行化许多串行的for循环,达到明显提高性能的效果。
1. AbsVal: 有两种接口,forward和forward_inplace, 区别就是inplace操作原地替换,不会额外申请新内存空间,具体操作时,在channel维度做pragma omp parallel for并行加速,若bottom value为正,则top value = bottom value,否则取反。
2. ArgMax: 存在两种输出方式,1). 仅输出max index 2). 输出max index的同时,也会输出该index对应的val。具体使用哪种输出方式,通过load_param(FILE* paramfp)接口中载入的out_max_val参数来决定,若out_max_val为真,则为2)方式输出,输出时前topk的值为max index, 后topk个值为max val;否则为方式1输出。
int nscan = fscanf(paramfp, "%d %d", &out_max_val, &topk);
值得一提的是内部针对topk的排序,ncnn接口中使用的std::partial_sort接口。
std::partial_sort(vec.begin(), vec.begin() + topk, vec.end(), std::greater< std::pair<float, int> >());
3. BatchNorm: BatchNorm也有两种接口,forward和forward_inplace, 不做过多赘述。核心优化还是在于初始化时算好了全部的预置计算,在实际forward时降低计算量。
#pragma omp parallel for
for(int q = 0; q < channels; q++){
const float* ptr = bottom_blob.channel(q);
float* outptr = top_blob.channel(q);
float a = a_data_ptr[q];
float b = b_data_ptr[q];
for(int i=0; i<size; i++){
outptr[i] = b*ptr[i] + a;
}