鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

案例Demo

可通过JavaVectorHelper工具对单个文件/整个项目进行扫描,本章节基于单个文件提供对应可用向量化的示例代码,示例代码片段功能是对数组间运算并赋值,代码仅供参考。

  1. 扫描前源码文件如图1所示。
    图1 BpVectorReorderer.java
  2. 运行BpVectorReorderer.java文件中的For循环。
    图2 改造前运行结果
  3. 使用JavaVectorHelper工具,识别出代码块中加粗显示的代码,可替换为可用向量化代码。
    private static boolean centroidValid(
            float[] centroid, FloatVectorValues vectors, IntsRef ids, int count) throws IOException {
          // recompute centroid to check the incremental calculation
          float[] check = new float[centroid.length];
          computeCentroid(ids, vectors, check, VectorSimilarityFunction.EUCLIDEAN);
          for (int i = 0; i < check.length; ++i) {
            float diff = Math.abs(check[i] - centroid[i]);
            if (diff > 1e-4) {
              return false;
            }
          }
          return true;
        }
        private static void swapIdsAndCentroids(
            IntsRef ids,
            int from,
            int to,
            int midPoint,
            FloatVectorValues vectors,
            float[] leftCentroid,
            float[] rightCentroid,
            float[] scratch,
            int count,
            VectorSimilarityFunction vectorScore)
            throws IOException {
          assert from < to;
          int[] idArr = ids.ints;
          int fromId = idArr[from];
          int toId = idArr[to];
          // Now update the centroids, this makes things much faster than invalidating it and having to
          // recompute on the next iteration.  Should be faster than full recalculation if the number of
          // swaps is reasonable.
          // We want the net effect to be moving "from" left->right and "to" right->left
          // (1) scratch = to - from
          if (count <= MAX_CENTROID_UPDATES && vectorScore == VectorSimilarityFunction.EUCLIDEAN) {
            int relativeMidpoint = midPoint - ids.offset;
            vectorSubtract(vectors.vectorValue(toId), vectors.vectorValue(fromId), scratch);
            // we must normalize to the proper scale by accounting for the number of points contributing
            // to each centroid
            // left += scratch / size(left)
            vectorScalarMul(1 / (float) relativeMidpoint, scratch);
            VectorUtil.add(leftCentroid, scratch);
            // right -= scratch / size(right)
            vectorScalarMul(-relativeMidpoint / (float) (ids.length - relativeMidpoint), scratch);
            VectorUtil.add(rightCentroid, scratch);
          }
          idArr[from] = toId;
          idArr[to] = fromId;
          if (count <= MAX_CENTROID_UPDATES) {
            assert centroidValid(
                leftCentroid, vectors, new IntsRef(idArr, ids.offset, midPoint - ids.offset), count);
            assert centroidValid(
                rightCentroid,
                vectors,
                new IntsRef(ids.ints, midPoint, ids.length - midPoint + ids.offset),
                count);
          }
        }
      /**
       * Adds the second argument to the first
       *
       * @param u the destination
       * @param v the vector to add to the destination
       **/
      static void vectorSubtract(float[] u, float[] v, float[] result) {
        for (int i = 0; i < u.length; i++) {
          result[i] = u[i] - v[i];//可替换为向量化代码
        }
      }
  4. 替换为向量化代码,若代码中定义了变量名称,替换后会自动引入所需要的import语句和需要声明的常量语句。
    static void vectorSubtract(float[] u, float[] v, float[] result) {
        int i = 0;//已替换为向量化代码
        for (; i < FLOAT_SPECIES.loopBound(u.length); i = i + FLOAT_SPECIES.length()) {
          FloatVector uVector = FloatVector.fromArray(FLOAT_SPECIES, u, i);
          FloatVector vVector = FloatVector.fromArray(FLOAT_SPECIES, v, i);
          uVector.sub(vVector).intoArray(result, i);
        }
        for (; i < u.length; i++) {
          result[i] = u[i] - v[i];
        }
      }

    需要声明的常量语句:

    private static final VectorSpecies<Float> FLOAT_SPECIES = FloatVector.SPECIES_PREFERRED;

    import语句:

    import jdk.incubator.vector.VectorSpecies;
    import jdk.incubator.vector.FloatVector;
  5. 运行BpVectorReorderer.java文件中改造后的For循环。
    图3 改造后运行结果

    编译运行改造后的文件,运行结果保持不变,性能有所提升。