当前位置: 首页 > news >正文

邵东建设公司网站哪家好网站扫码怎么做

邵东建设公司网站哪家好,网站扫码怎么做,网页设计与制作课程代码,工商注册服务平台俄罗斯Yandex开发的ClickHouse是一款性能黑马的OLAP数据库#xff0c;其对SIMD的灵活运用给其带来了难以置信的性能。本文我们聊聊它如何对过滤操作进行SIMD优化。 基本思想 1、有一个数组data#xff0c;即ColumnVector::data#xff0c;存放数据 2、使用uint8类型#xf… 俄罗斯Yandex开发的ClickHouse是一款性能黑马的OLAP数据库其对SIMD的灵活运用给其带来了难以置信的性能。本文我们聊聊它如何对过滤操作进行SIMD优化。 基本思想 1、有一个数组data即ColumnVector::data存放数据 2、使用uint8类型即1个字节类型的filter数组ICloumn::Filter。他的大小是data数组大小里面存放布尔值标记data数组里面哪些数据满足过滤条件应该筛选出来 3、最终生成一个新的数组res根据filter数组对data数组进行筛选满足条件的拷贝到res数组中。标量逻辑的简单伪码 let res [] for (let i 0; i data.size(); i ) {if (filter[i] ! 0) {res.append(data[i])} } Clickhouse如何实现的呢 4、上面代码耗时因素在于循环次数非常多等于data数组的大小 5、如果可以降低循环次数同时保证单次循环耗时变化不大总体执行效率更高。要满足上面条件需要在同一个指令周期做更多运算SIMD指令可以做这样的运算。 6、SIMD指令目前最大支持512位数据而filter本身一个值为8位单词循环处理数据量为512 / 8 64个 7、每次取出来64个filter数组项64字节将其组成一个64位无符号整数值mask这样每个filter数组项占用一个比特位 8、有两种特殊情况1mask 64位比特位都是1本次循环中64个data项都应该拷贝到res中。2mask 64位比特位都是0可以直接跳过循环。当然这两种特殊情况经常出现在业务常见中 9、第三中情况是有一部分满足条件此时是否需要循环64次有没有进一步的优化方法看看clickhouse咋处理 10、有多少项需要拷贝到新数组取决于mask中比特位为1的个数通过__builtin_clzll内置函数得到入参64位二进制表示形式中开头0的个数从而得到最高比特位为1的索引继而知道哪项数据需要拷贝。 11、最高1比特位的数据项拷贝后需要将它置成0这里有2个比较高效的方法blsr函数一个是_blsr_u64指令另一个是mask (mask-1) 12、循环设置最高1的比特位直到mask中所有比特位都为0 ColumnVectorT::filter函数 过滤函数主要是filter函数。其实分为3部分AVX512VBMI2指令集、默认的操作和尾部数据处理。其中尾部数据处理是指处理数据不够64个时剩余的部分处理方式这种方式无法使用SIMD沿用标量处理方式。 先看下默认操作方式doFilterAligned即模板函数   这部分其实是对有一部分值满足条件场景的优化主要有3个方面 1前导0个数即data数组data[0]--data[i]都满足条件需要拷贝到结果中 2后导0个数即data数组data[i]--data[63]都满足条件需要拷贝到结果中 3其他场景比如0011 1100的场景即两边都有不满足条件的那就需要特殊处理了计算出最低位起0的个数index然后将data_pos[index]拷贝到结果中即该数组满足条件最后将index位置为0。 前缀和后缀拷贝的判断 蓝色框表示的意义其实是去除前导0后剩余的都是1即mask值。也就是从0的索引开始到64 - leading_zeroes都需要拷贝到结果中。蓝框计算效果以2个字节大小为例前导5个0: 后导0的处理其实可以调用__buitlin_ctzll函数 uint8_t suffixToCopy(UInt64 mask) {const auto prefix_to_copy prefixToCopy(~mask);//mask值取反return prefix_to_copy 64 ? prefix_to_copy : 64 - prefix_to_copy;//需要拷贝个数 } 效果如下图所示 64字节值转换成64位掩码值的计算函数Bytes64MaskToBits64Mask实现也很有讲究 /// Transform 64-byte mask to 64-bit mask inline UInt64 bytes64MaskToBits64Mask(const UInt8 * bytes64) { #if defined(__AVX512F__) defined(__AVX512BW__)const __m512i vbytes _mm512_loadu_si512(reinterpret_castconst void *(bytes64));UInt64 res _mm512_testn_epi8_mask(vbytes, vbytes); #elif defined(__AVX__) defined(__AVX2__)const __m256i zero32 _mm256_setzero_si256();UInt64 res (static_castUInt64(_mm256_movemask_epi8(_mm256_cmpeq_epi8(_mm256_loadu_si256(reinterpret_castconst __m256i *(bytes64)), zero32))) 0xffffffff)| (static_castUInt64(_mm256_movemask_epi8(_mm256_cmpeq_epi8(_mm256_loadu_si256(reinterpret_castconst __m256i *(bytes6432)), zero32))) 32); #elif defined(__SSE2__)const __m128i zero16 _mm_setzero_si128();UInt64 res (static_castUInt64(_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_castconst __m128i *(bytes64)), zero16))) 0xffff)| ((static_castUInt64(_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_castconst __m128i *(bytes64 16)), zero16))) 16) 0xffff0000)| ((static_castUInt64(_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_castconst __m128i *(bytes64 32)), zero16))) 32) 0xffff00000000)| ((static_castUInt64(_mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_castconst __m128i *(bytes64 48)), zero16))) 48) 0xffff000000000000); #elif defined(__aarch64__) defined(__ARM_NEON)const uint8x16_t bitmask {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};const auto * src reinterpret_castconst unsigned char *(bytes64);const uint8x16_t p0 vceqzq_u8(vld1q_u8(src));const uint8x16_t p1 vceqzq_u8(vld1q_u8(src 16));const uint8x16_t p2 vceqzq_u8(vld1q_u8(src 32));const uint8x16_t p3 vceqzq_u8(vld1q_u8(src 48));uint8x16_t t0 vandq_u8(p0, bitmask);uint8x16_t t1 vandq_u8(p1, bitmask);uint8x16_t t2 vandq_u8(p2, bitmask);uint8x16_t t3 vandq_u8(p3, bitmask);uint8x16_t sum0 vpaddq_u8(t0, t1);uint8x16_t sum1 vpaddq_u8(t2, t3);sum0 vpaddq_u8(sum0, sum1);sum0 vpaddq_u8(sum0, sum0);UInt64 res vgetq_lane_u64(vreinterpretq_u64_u8(sum0), 0); #elseUInt64 res 0;for (size_t i 0; i 64; i)res | static_castUInt64(0 bytes64[i]) i; #endifreturn ~res; } 我们看到按照优先级尽可能利用位数多的指令集进行计算同时在所有指令集都不可用及未64字节对齐(align)的部分进行了保底处理。其利用了以下指令集:     AVX512F / AVX512BW     AVX/AVX2     SSE2 其中_mm512_testn_epi8_mask函数功能计算a和b两个入参值按8位整数逐位与AND产生中间8位值如果中间值为0则在结果掩码k中设置相应位 FOR j : 0 to 63   i : j*8   k[j] : ((a[i7:i] AND b[i7:i]) 0) ? 1 : 0 ENDFOR 所以bytes64MaskToBits64Mask最终计算出的值需要取反。另外其他指令集比如AVX下_mm256_cmpeq_epi8比较32位是否等于0等于0表示不满足条件当然等于零时该函数返回0xFF所以同样最终结果需要取反。 另外一种操作方式doFilterAligned即模板函数 主要是通过_mm512_mask_compressstoreu_epi8类似函数分别对1、2、4、8字节长度类型针对掩码进行数据拷贝这里不再赘述。 参考 https://zhuanlan.zhihu.com/p/454657709 https://blog.csdn.net/u010002184/article/details/113977586 https://blog.51cto.com/u_15103025/2643507 https://zhuanlan.zhihu.com/p/449154820 https://www.zhihu.com/question/450069375/answer/1813516193 https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html
http://www.tj-hxxt.cn/news/137951.html

相关文章:

  • 河北网站建设价格大全承德网站建设制作
  • 做包装盒效果图网站seo推广业务员招聘
  • 网站开发难度django 电商网站开发
  • app网站开发方案博采网络科技
  • 福州网站建设yfznkj定制应用软件有哪些
  • 杭州哪些做网站公司linux wordpress是什么意思
  • 美食网站开发的意义wordpress数据库二次开发
  • 莱芜做网站的公司科技有限公司可以做网站建设吗?
  • 旅游前 做攻略有什么网站好用商城网站html模板
  • 盘锦做网站公司wordpress 文章数据
  • 麦壳云网站建设网络规划的内容是什么
  • 网站开发技术有永久建站平台
  • 昆明做网站设计昆明手机网站开发
  • win2008 r2 搭建网站网站建设如何创建框架页面
  • 公司网站建设哪家好成都兼职建设网站
  • 清河做网站哪里便宜网络规划与设计报告总结
  • 网站建设需具备的条件学校网站logo怎么做
  • 新乡市网站建设电脑培训班宁波seo外包
  • 校本教研网站建设方案热 综合-网站正在建设中
  • 如何检测网站被搜索引擎惩罚了asp.net网站配置文件
  • 宜家有做自己的网站吗什么是网站快照
  • 利于seo的网站设计哪个网站可以做房产信息群发
  • 南沙网站建设公司营销公司网站模板下载
  • 宜兴做网站哪家好搜狐快站建设pc网站
  • 如何确定网站建设空间门户网站建设采购
  • 程序员是不是都是做网站的网站建设制作设计珠海
  • 河南省建设网站桂林漓江阳朔
  • 房地产网站系统wordpress 获取附件链接
  • 手机网站建设的优势免费ppt
  • 临沂龙文网站建设网站建设策划书事物选题