【问题标题】:Is this bit conversion process vectorizable? (MATLAB)这个位转换过程是否可向量化? (MATLAB)
【发布时间】:2025-12-04 06:25:01
【问题描述】:

我正在尝试加快位转换过程,该过程当前处于 MATLAB 循环中并且需要很长时间才能执行。问题来了:

考虑一个大小为12xNinput 整数矩阵,其中N 可以很容易地为100,000 左右。然后我执行以下操作:

output = zeros(3, N);
temp = zeros(3,1);

% Loop through each column
for pp = 1 : N            

     % For each column, convert the first 4 numbers into a float, the second 4 numbers into a float, and finally the third 4 numbers into a float as so:
     for dd = 1:3 
        snip = input(dd * 4 : -1 : (dd-1) * 4 + 1, pp);
        temp(dd) = typecast(uint32(bin2dec(num2str(reshape(dec2bin(snip,8).',1, 32))) ), 'single');        
     end

     % Now simply store the result
     output(1:3,pp) = temp;
end  

我基本上是将每列转换为 3 个浮点数,但我想看看是否有任何方法可以加快此过程,并删除您在此处看到的循环。

有没有这样的方法?谢谢!

编辑:

这里有一个例子来说明我的目标:假设我们的inputMatrix 是一个12 x 4,由:

   65   65   66   65
  164  168  175  174
  130  232    2  222
   16  138   86   27
   64   64   66   65
  209  240   59   12
  136  185  207  101
  103   33   18  172
  190  190   64  190
  185  182  121  184
   36   41  153  173
   19   55  127  183

转换后的输出(请参阅here 了解通过 IEEE-754 标准转换/解包到浮点),将是 output 的值:

    20.5635   21.1135   87.5046   21.8584
    6.5479    7.5226   46.9522    8.7748
   -0.3616   -0.3558    3.9000   -0.3607

因此,inputMatrix 的第一个 12 元素列将给出 output 的第一个 3 元素列。 (换句话说,[16, 164, 30, 16] 将给出 20.5635,而 [16, 64, 209, 136] 将给出 6.5479 等)。

我想要做的是,它尽可能地将这个矩阵上的这个操作向量化。谢谢!

【问题讨论】:

    标签: performance matlab type-conversion bit-manipulation vectorization


    【解决方案1】:

    typecast 是矢量化的,因此您可以将整个输入数组提供给它。 (注意input 是一个内置函数的名字,所以你真的应该给你的变量取个别的名字。)结果是一个列向量,所以你需要在之后重塑它。

    我不得不翻转输入数组中的字节顺序,所以我只是对整个数组执行了flipud。这会使生成的浮点数以错误的顺序排列,所以我只是在结果上重复了flipud

    >> A = [   65   65   66   65
              164  168  175  174
              130  232    2  222
               16  138   86   27
               64   64   66   65
              209  240   59   12
              136  185  207  101
              103   33   18  172
              190  190   64  190
              185  182  121  184
               36   41  153  173
               19   55  127  183];    
    
    >> Af=flipud(uint8(A));
    
    >> B = flipud(reshape(typecast(Af(:), 'single'), 3, []))
    B =
    
       20.56351   21.11354   87.50456   21.85845
        6.54790    7.52260   46.95222    8.77482
       -0.36160   -0.35578    3.89999   -0.36070
    

    更新:我以前的版本(在 Octave 上运行)只是对完整矩阵 A 进行类型转换。 MATLAB 显然更挑剔,需要一个向量,因此更新使用A(:) 将矩阵转换为列向量。其他一切都一样。

    【讨论】:

    • 嗨烧杯,由于某种原因,我的类型转换抱怨“第一个参数必须是向量”......
    • 我们在 MATLAB 上得到了相同的行为(我在 Octave 上测试过)。我会更新答案。
    • 嗨烧杯,好的,所以 (:) 运算符处理了这个问题,但我认为(实际转换的)答案在我的代码和您的代码之间并不相同。我认为我的代码中的微妙之处在于允许我获取一个输入列,并给出 3 个浮点数。您的代码中没有发生这种转换...谢谢。
    • 如果您可以提供一些示例输入和输出(可能是 1 或 2 列),也许我可以看到有什么区别。
    • 我认为我们遇到了字节排序问题。我们应该能够轻松解决这个问题,但我想从您那里获得一些样本数据,以便我可以验证而不是仅仅猜测。 :)
    最近更新 更多