程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快?

开发过程中遇到Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快的问题如何解决?下面主要结合日常开发的经验,给出你关于Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快的解决方法建议,希望对你解决Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快有所启发或帮助;

目前,我在我的函数中发现了一些奇怪的行为。我有一个从 (x,a,b) -> (x,y,z) 转换的转换函数。我正在使用 Data.Vector.Storable,因为我正在与一些外部库进行通信。 我估计测试数据集的传递函数的时间低于十几秒。 但是我的实施速度慢得要命!这是某种:

import Data.Complex
import System.Random
import qualifIEd Data.Vector as V
import qualifIEd Data.Vector.Storable as VS

nx = 128
ny = 128
nz = 128
na = 128
nb = 16

transform :: Vs.Vector (Complex float) -> Vs.Vector (Complex float)->Vs.Vector (Complex float)->Vs.Vector (Complex float)
transform !inData !transfAArray !transfbarray= Vs.concatMap
    (\x ->
       Vs.concatMap
         (\y ->
            Vs.map
              (\z ->
                 calcSum y z X) $
            Vs.enumFromN 0 nz) $
       Vs.enumFromN 0 ny ) $
  Vs.enumFromN 0 nx
  where
    calcSum :: Int -> Int -> Int -> Complex float
    calcSum y z x =
      Vs.sum $
      Vs.map
        (\b ->
           (*) (transfB y b) $ dotProd (transfA z) (inDataSlice x b) ) $
           -- (*) (transfB y b) $ dotProd (transfA z) (transfA z) ) $ Is fast
      Vs.enumFromN 0 nb
    dotProd !a1 !a2 = Vs.sum $ Vs.zipwith (*) a1 a2
    inDataSlice x b = Vs.slice (x*na*nb + b*na) na inData
    transfA z =  Vs.slice (z * na) na transfAArray
    transfB y b =  VS.UnsafeIndex transfbarray (y * nb + b)





randomComplex :: IO (Complex float)
randomComplex = (:+) <$> randomIO <*> randomIO

main :: IO ()
main = do
  inData <- Vs.generateM (nx * na * nb) (\i -> randomCompleX) 
  transfAArray <- Vs.generateM (nz * na) (\i -> randomCompleX)
  transfbarray <- Vs.generateM (ny * nb) (\i -> randomCompleX)

  let !outData = transform inData transfAArray transfbarray 
  print $ Vs.sum outData

完成这需要几分钟!如果我激活第 35 行,它工作得非常快 - 所以我猜一定有一些与流融合有关的东西(分析显示了很多 >>= 在这个过程中)。我在 C++ 中重新创建了代码并获得了大约 5 秒的运行时间(单线程):

#include <String>
#include <iterator>
#include <iostream>
#include <algorithm>
#include <vector>
#include <complex>
#include <cmath>
#include <numeric>
 
int main()
{
    // transformation [nx*na*nb] -> [nx*ny*nz]
    // [x][y][z],with dimensions 128 128 128
    const unsigned int nx = 128;
    const unsigned int ny = 128;
    const unsigned int nz = 128;
    std::vector<std::complex<float>> out(nx*ny*nz);

    const unsigned int na = 128;
    const unsigned int nb = 16;
    std::vector<std::complex<float>> in(nx * na * nb);
    std::iota (std::begin(in),std::end(in),0);

    std::vector<std::complex<float>> transa(na * nz);
    std::iota (std::begin(transa),std::end(transa),0);
    std::vector<std::complex<float>> transB(nb * ny);
    std::iota (std::begin(transB),std::end(transB),0);

    for (int x = 0; x < nx; x++) {
        for (int y = 0; y < ny; y++) {
            for (int z = 0; z < nz; z++) {
                for (int b = 0; b < nb; b++) {
                    std::complex<float> sum = 0;
                    for (int a = 0; a < na; a++) {
                        sum += transa[z*na + a] * in[x*na*nb+b*na+a];
                    }
                    out[x*ny*nz + y*nz + z]= sum * transB[b * ny + y];
                }
            }
        }
    }

    std::cout << out[12] << "done\n";
}

在我绝望的最后几天,我发现了以下奇怪的行为: 如果我用 Data.Vector.UnBoxed 替换 Data.Vector.Storable,它的运行速度和 C++ 代码一样快!

所以……为什么?

  1. 据我所知,unBoxed 和 storable 都使用连续的内存区域 - 因此缓存/内存访问时间应该没有问题。
  2. 在可存储版本中为堆分配了 TB,而未装箱版本只使用了几 MB。我感觉 Storable 版本不断地在内存中移动块。

有什么想法吗?是否有一种简单的方法可以通过 Storage 实现类似的速度? (我正在使用 Stack 中的 ghc-8.10.4)

(PS:总是用 -O2 编译,有时也用 -fllvm -optlo-O2 :)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

大佬总结

以上是大佬教程为你收集整理的Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快全部内容,希望文章能够帮你解决Data.Vector.Storable.ZipWith 中的流融合速度较慢,但​​ Data.Vector.Unboxed.ZipWith 中的流融合速度较快所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。