c++ SIMD AVX2比较 例子

c++ SIMD AVX2比较 例子示例代码含义:记目标字符串中有多少个目标字符。linux代码(例子)如下:#include<iostream>#include<x86intrin.h>#include<fstream>#include<chrono>usingnamespacestd;structStringView{constchar*p;constsize_tlen;};StringViewFileSize(const

大家好,又见面了,我是你们的朋友全栈君。

示例代码含义:记目标字符串中有多少个目标字符。
linux代码(例子)如下:

#include <iostream>
#include <x86intrin.h>
#include <fstream>
#include <chrono>
using namespace std;
struct StringView { 

const char* p;
const size_t len;
};
StringView FileSize(const char* fileName) { 

ifstream ifstr(fileName);
const auto b = ifstr.tellg();
ifstr.seekg(0, ios::end);
const auto e = ifstr.tellg();
const size_t fileSize = e - b;
ifstr.seekg(0, ios::beg);
char *p = new char[fileSize];
ifstr.read(p, fileSize);
return { 
p, fileSize};
}
// Normal function
size_t count_c_normal(const StringView& str, const uint8_t c) { 

uint32_t num = 0;
for (uint32_t i = 0; i < str.len; ++i) { 

if (c == *(str.p + i)) { 

++num;
}
}
return num;
}
// SIMD function
size_t count_c_simd(const StringView& str, const uint8_t c) { 

__m128i ch = _mm_set1_epi8(c); // char ch[16] = { c, c, ..., c }
size_t cnt = 0;
uint32_t i = 0;
for (; i < str.len; i+=16) { 

// char t[16] = { (str+i)[0], (str+i)[1], ... }
__m128i t = _mm_loadu_si128((__m128i *)(str.p + i));
__m128i res = _mm_cmpeq_epi8(t, ch);
// res[16] = { 0xFF, 0x00, 0xFF ... }
unsigned mask = _mm_movemask_epi8(res);
// bits[16] = 0...1101
cnt += __builtin_popcount(mask);
}
// free cnt .
for (; i < str.len; ++i) { 

if (c == *(str.p + i))
{ 

++cnt;
}
}
return cnt;
}
// AVX function
size_t count_c_avx256(const StringView& str, const uint8_t c) { 

__m256i ch = _mm256_set1_epi8(c); // char ch[16] = { c, c, ..., c }
size_t cnt = 0;
uint32_t i = 0;
for (; i < str.len; i+=32) { 

// char t[16] = { (str+i)[0], (str+i)[1], ... }
__m256i t = _mm256_loadu_si256((__m256i *)(str.p + i));
__m256i res = _mm256_cmpeq_epi8(t, ch);
// res[16] = { 0xFF, 0x00, 0xFF ... }
unsigned mask = _mm256_movemask_epi8(res);
// bits[16] = 0...1101
cnt += __builtin_popcount(mask);
}
// free cnt .
for (; i < str.len; ++i) { 

if (c == *(str.p + i))
{ 

++cnt;
}
}
return cnt;
}
int main() { 

const auto ret = FileSize("./test_file");
size_t cnt1 = 0, cnt2 = 0, cnt3 = 0;
const auto t1 = std::chrono::steady_clock::now();
cnt1 = count_c_normal(ret, uint8_t('1'));
const auto t2 = std::chrono::steady_clock::now();
cnt2 = count_c_simd(ret, uint8_t('1'));
const auto t3 = std::chrono::steady_clock::now();
cnt3 = count_c_avx256(ret, uint8_t('1'));
const auto t4 = std::chrono::steady_clock::now();
std::cout << "cnt1:" << cnt1 << ",cnt2:" << cnt2 << ",cnt3:" << cnt3 << std::endl;
const auto d1 = std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count();
const auto d2 = std::chrono::duration_cast<std::chrono::milliseconds>(t3-t2).count();
const auto d3 = std::chrono::duration_cast<std::chrono::milliseconds>(t4-t3).count();
std::cout << "time1:" << d1 << ",time2:" << d2 << ",time3:" << d3 << std::endl;
return 0;
}

生成随机文件代码详见:https://blog.csdn.net/weixin_41644391/article/details/113526563

编译命令:g++ -std=c++11 main.cc -o main -mavx -mavx2 -O2
性能:

普通O2:1890ms,simd:509ms,avx2:253ms

因为编译命令中加了avx2,怀疑simd的代码也被avx2优化了。纯simd结果可见:https://blog.csdn.net/weixin_41644391/article/details/113526563

其他:基于avx512的测试因为不支持gcc4.8.5,所以需要等一段时间才能出来。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144029.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • c语言 hex转str 函数_int printf(const char)

    c语言 hex转str 函数_int printf(const char)voidhexDump(constchar*buf,intlen){ if(len&lt;1||buf==NULL)return; constchar*hexChars="0123456789ABCDEF"; inti=0; charc=0x00; charstr_print_able[17]; charstr_hex_buffe…

  • 前端开发技术(vscode怎么下载)

    前言   在前端开发中,有一个非常好用的工具,VisualStudioCode,简称VScode。   都不用我安利VScode,大家就会乖乖的去用,无数个大言不惭的攻城狮,都被VScode比德芙还丝滑的强大功能所折服。   我是来给大家安利插件的,想做个比较全面的插件集合给大家。网上的我也看过一些,但是都比较零散,时间也久了一些,我结合最近的情况,总结一下,造福大家,才是我…

  • MATLAB快速搭建一个神经网络以及神经网络工具箱的使用

    MATLAB快速搭建一个神经网络以及神经网络工具箱的使用文章目录0.导读1.神经网络工具箱2.如何利用MATLAB工具箱建立神经网络人工神经网络学习笔记2——MATLAB神经网络工具箱神经网络工具箱的使用MATLAB中神经网络工具箱的使用0.导读首先声明,这篇文章的内容并不全是本人的原创内容,凡是引用了别人的博客或者文章的地方,我都会标注出来,以便大家阅读原文。现在最前面的,当然是提纲挈领的废话。凡是商品都有目标人群,文章也该如此,一篇文章写了…

  • android默认打开方式修改_setcontenttype方法

    android默认打开方式修改_setcontenttype方法android打开文件,intent的使用

    2022年10月14日
  • wireshark抓包工具详细说明及操作使用_wireshark ping抓包

    wireshark抓包工具详细说明及操作使用_wireshark ping抓包wireshark是非常流行的网络封包分析软件,功能十分强大。可以截取各种网络封包,显示网络封包的详细信息。使用wireshark的人必须了解网络协议,否则就看不懂wireshark了。为了安全考虑,wireshark只能查看封包,而不能修改封包的内容,或者发送封包。wireshark能获取HTTP,也能获取HTTPS,但是不能解密HTTPS,所以wireshark看不懂HTTPS中的

  • QQ浏览器谷歌版吾爱破解(QQ浏览器最新谷歌版)

    ubuntu软件安装大全本文基于ubuntu16.04系统本文提供下载地址:安装包地址:https://github.com/weiguow/ubuntu-software.gitdeepin-wine地址:https://github.com/weiguow/deepin-wine-ubuntu.git1.Chrome浏览器sudowgethttps://repo.fdzh.o…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号