聊聊Doris向量化执行引擎-过滤操作

简介: 聊聊Doris向量化执行引擎-过滤操作

聊聊Doris向量化执行引擎-过滤操作Doris是开源的新一代极速MPP数据库,和StarRocks同源,采用全面向量化技术,充分利用CPU单核资源,将单核执行性能做到极致。本文,我们聊聊过滤操作是如何利用SIMD指令进行向量化操作。过滤操作的SIMD向量化函数是_evaluate_vectorization_predicate:和StarRocks实现大致类似,但稍有不同:  SegmentIterator::_evaluate_vectorization_predicate执行过程如下图所示:

1、通过1个字节bool类型的ret_flags数组来表示是否满足过滤条件,1表示满足条件,0表示不满足2、AVX2指令集环境下:通过_mm256_loadu_si256封装的指令函数加载256位长度值到寄存器,也就是32字节值f3、_mm256_setzero_si256生成256位的0值all04、_mm256_cmpgt_epi8函数将f和all0每个字节进行并行比较,也就是32个字节并行比较,f中字节>all0中字节值时,对应结果位为1,否则为05、将第4步的值通过_mm256_movemask_epi8转换成int整数mask。比如10001111111111111,转换后为36863,其中ret_flags[0]为1,ret_flags[1]为0...6、mask等于0,表示没有一个满足条件。7、mask等于0xffffffff,表示全部满足条件,需要将32个数据的行号保存到数组sel_rowid_idx[]中8、mask等于其他值时,表示有一部分值满足条件。这个时候需要特殊处理:1)通过__builtin_ctzll(mask)计算mask中末尾0的个数bit_pos。比如:11100000:有5个02)sel_rowid_idx[new_size++] = sel_pos + bit_pos;后导第一个满足条件的行号保存到sel_rowid_idx数组中3)mask = mask & (mask - 1)跳过不满足的行,StarRocks实现方式:mask右移6位,即11,值3。4)当然还需要处理尾数据,也就是SIMD对其后剩余的部分:按照标量处理方式处理

    for (; sel_pos < sel_end; sel_pos++) {
        if (ret_flags[sel_pos]) {
            sel_rowid_idx[new_size++] = sel_pos;
        }
    }

    5)返回1)步继续计算。9、当然,上述涉及mask的计算,仅说明了AVX指令集下实现方式,同时还实现了SSE2指令集

      inline uint32_t bytes32_mask_to_bits32_mask(const uint8_t* data) {
      #ifdef __AVX2__
          auto zero32 = _mm256_setzero_si256();
          uint32_t mask = static_cast<uint32_t>(_mm256_movemask_epi8(
                  _mm256_cmpgt_epi8(_mm256_loadu_si256(reinterpret_cast<const __m256i*>(data)), zero32)));
      #elif defined(__SSE2__) || defined(__aarch64__)
          auto zero16 = _mm_setzero_si128();
          uint32_t mask =
                  (static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpgt_epi8(
                          _mm_loadu_si128(reinterpret_cast<const __m128i*>(data)), zero16)))) |
                  ((static_cast<uint32_t>(_mm_movemask_epi8(_mm_cmpgt_epi8(
                            _mm_loadu_si128(reinterpret_cast<const __m128i*>(data + 16)), zero16)))
                    << 16) &
                   0xffff0000);
      #else
          uint32_t mask = 0;
          for (std::size_t i = 0; i < 32; ++i) {
              mask |= static_cast<uint32_t>(1 == *(data + i)) << i;
          }
      #endif
          return mask;
      }

      关键原理同样是将32字节的select数组,转变成32bit位的无符号整数来操作

      目录
      相关文章
      |
      7月前
      |
      SQL 存储 调度
      从 Volcano 火山模型到 Pipeline 执行模型,阿里云数据库 SelectDB 内核 Apache Doris 执行模型的迭代
      一个合适的执行模型对于提高查询效率和系统性能至关重要。本文全面剖析 Apache Doris Pipeline 执行模型的设计与改造历程,并在 2.1 版本对并发执行模式与调度模式进一步优化,解决了执行并发受限、执行及调度开销大等问题。
      从 Volcano 火山模型到 Pipeline 执行模型,阿里云数据库 SelectDB 内核 Apache Doris 执行模型的迭代
      |
      6月前
      |
      分布式计算 大数据 调度
      MaxCompute产品使用问题之如何解决UDF针对数据每行操作,而XGBoost需要对数据整体操作的问题
      MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
      |
      7月前
      |
      消息中间件 网络协议 大数据
      [flink 实时流基础]源算子和转换算子
      [flink 实时流基础]源算子和转换算子
      |
      7月前
      |
      存储 分布式计算 API
      adb spark的lakehouse api访问内表数据,还支持算子下推吗
      【2月更文挑战第21天】adb spark的lakehouse api访问内表数据,还支持算子下推吗
      145 2
      |
      7月前
      |
      SQL 消息中间件 监控
      流计算中的流式SQL是什么?请解释其作用和用途。
      流计算中的流式SQL是什么?请解释其作用和用途。
      141 0
      |
      7月前
      |
      存储 分布式计算 分布式数据库
      对给定的数据利用MapReduce编程实现数据的清洗和预处理,编程实现数据存储到HBase数据库,实现数据的增删改查操作接口
      对给定的数据利用MapReduce编程实现数据的清洗和预处理,编程实现数据存储到HBase数据库,实现数据的增删改查操作接口
      54 0
      |
      SQL NoSQL Java
      SQL查询引擎原理浅析
      # SQL的诞生 SQL英文全称是Structured Query Language,中文名即结构化查询语言,是一门专门用来查询数据的声明式编程语言。 我先解释一下声明式语言的概念,编程语言有两个分类: * 命令式:手把手教机器做事情 * 声明式:告诉机器任务,让它自己想办法解决 举个例子,假设你家里有机器人,你想让它帮忙拿一个在客厅桌子上的白色杯子给你。 如果用命令式编程的方
      622 0
      SQL查询引擎原理浅析
      |
      SQL 数据库 OceanBase
      聊聊OceanBase的向量化过滤
      聊聊OceanBase的向量化过滤
      151 0
      聊聊OceanBase的向量化过滤
      |
      数据库
      聊聊StarRocks向量化执行引擎-过滤操作
      聊聊StarRocks向量化执行引擎-过滤操作
      275 0
      |
      OLAP 数据处理 数据库
      聊聊ClickHouse向量化执行引擎-过滤操作
      聊聊ClickHouse向量化执行引擎-过滤操作
      340 0