SPARK的计算向量化-spark本身的向量化

89 篇文章 10 订阅
68 篇文章 0 订阅

背景

我们知道,随着计算引擎战争的结束(SPARK赢得了离线处理的霸权),越来越多的公司致力于性能的优化,而引擎的优化,目前直指计算的向量化,
这片文章来说说spark本身对于向量化的实现。

spark本身的优化

我们都知道spark的Tungsten项目,这个项目中有一点就是Code Generation(代码生成)。代码生成除了消除虚函数的调用等功能外,其实在向量化这块也是做了处理的。
直接跳到ColumnarToRowExec代码:

val columnarBatchClz = classOf[ColumnarBatch].getName
    val batch = ctx.addMutableState(columnarBatchClz, "batch")
  ...
 val localIdx = ctx.freshName("localIdx")
    val localEnd = ctx.freshName("localEnd")
    val numRows = ctx.freshName("numRows")
    val shouldStop = if (parent.needStopCheck) {
      s"if (shouldStop()) { $idx = $rowidx + 1; return; }"
    } else {
      "// shouldStop check is eliminated"
    }
    s"""
       |if ($batch == null) {
       |  $nextBatchFuncName();
       |}
       |while ($limitNotReachedCond $batch != null) {
       |  int $numRows = $batch.numRows();
       |  int $localEnd = $numRows - $idx;
       |  for (int $localIdx = 0; $localIdx < $localEnd; $localIdx++) {
       |    int $rowidx = $idx + $localIdx;
       |    ${consume(ctx, columnsBatchInput).trim}
       |    $shouldStop
       |  }
       |  $idx = $numRows;
       |  $batch = null;
       |  $nextBatchFuncName();
       |}
     """.stripMargin

spark中向量化的核心就在于这块代码中,这块代码主要的就是ColumnarBatch,也就是列批,这种列批的数据结构,用FOR循环这种方式进行数据的访问,
这在JIT中会进行优化(优化成向量化)。
而这里还有一个重点就是:Parquet或者ORC这种列式存储,读取出来的时候,天然就是一个列批的数据结构,很方便做向量化操作。

但是,利用JIT进行向量化是有缺点的:
利用了JIT进行优化,这个是需要编译器追踪循环的次数的,如果循环次数不够,就不会进行进行JIT,也就无法做到向量化。
所以好多公司把这种着力于用其他语句实现来进行真正意义上的向量化。

参考

本文参考了

  1. 深度解读|Spark 中 CodeGen 与向量化技术的研究
  2. Velox: 现代化的向量化执行引擎
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
K-means 算法是一种无监督学习算法,用于将数据集分成 K 个簇。Spark MLlib 中实现了 K-means 算法,可以用于大规模数据的聚类。 以下是 Spark MLlib 实现 K-means 算法的基本步骤: 1. 加载数据集,将数据集转换为特征向量 2. 初始化 K 个簇的质心 3. 对每个样本,将其分配到距离最近的簇 4. 根据分配结果,重新计算每个簇的质心 5. 重复步骤 3 和 4,直到达到最大迭代次数或收敛 以下是一个简单的代码示例: ```python from pyspark.ml.clustering import KMeans from pyspark.ml.evaluation import ClusteringEvaluator from pyspark.ml.feature import VectorAssembler # 加载数据集 data = spark.read.format("csv").load("path/to/data.csv", header=True, inferSchema=True) # 转换数据集为特征向量 assembler = VectorAssembler(inputCols=data.columns, outputCol="features") dataset = assembler.transform(data) # 初始化 KMeans 模型 kmeans = KMeans().setK(2).setSeed(1) # 训练模型 model = kmeans.fit(dataset) # 输出簇中心点 centers = model.clusterCenters() for center in centers: print(center) # 预测数据集中每个样本所属的簇 predictions = model.transform(dataset) # 评估模型 evaluator = ClusteringEvaluator() silhouette = evaluator.evaluate(predictions) print("Silhouette with squared euclidean distance = " + str(silhouette)) ``` 这里假设数据集已经被加载并且包含两个特征。首先,使用 VectorAssembler 将数据集转换为特征向量。然后,初始化 KMeans 模型并训练它。最后,输出每个簇的中心点和模型评估结果。需要注意的是,这里使用了默认的欧几里得距离作为距离度量。如果需要使用其他距离度量,可以通过设置 distanceMeasure 参数来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值