Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 短长度循环卷积的优化_Algorithm_Convolution_Micro Optimization - Fatal编程技术网

Algorithm 短长度循环卷积的优化

Algorithm 短长度循环卷积的优化,algorithm,convolution,micro-optimization,Algorithm,Convolution,Micro Optimization,我有两个8个无符号字节的序列,我需要计算它们的循环卷积,这会产生8个无符号19位整数。当我重复这百万次时,我想要优化 简单的方法需要64个MAC操作。我已经知道如何通过SSE/AVX指令来加速这一过程,这不是我想要的 是否有另一种方法,可能是基于FFT或数论变换来减少运算次数或其他技术来获得一些加速 实际上,我不需要8个值:最大值和相应的移位就足够了。循环卷积可以通过对每个输入进行离散傅里叶变换(DFT),乘以变换,然后进行逆DFT来计算。使用快速傅里叶变换算法,DFT及其逆可以在N*log(N

我有两个8个无符号字节的序列,我需要计算它们的循环卷积,这会产生8个无符号19位整数。当我重复这百万次时,我想要优化

简单的方法需要64个MAC操作。我已经知道如何通过SSE/AVX指令来加速这一过程,这不是我想要的

是否有另一种方法,可能是基于FFT或数论变换来减少运算次数或其他技术来获得一些加速


实际上,我不需要8个值:最大值和相应的移位就足够了。

循环卷积可以通过对每个输入进行离散傅里叶变换(DFT),乘以变换,然后进行逆DFT来计算。使用快速傅里叶变换算法,DFT及其逆可以在
N*log(N)
运算中计算,然后再进行N次运算以将变换相乘。因此,粗略地说,您需要
3N*log(N)+N
操作,对于8的输入大小计算为80。而且,FFT方法中的运算是复数运算,而不仅仅是MAC运算

但是,还有一个优化:因为输入数据是真实的,所以可以在不丢失信息的情况下用N/2+1复杂点表示变换。存在利用此属性的实值变换(和逆变换)。根据经验,这相当于执行长度为一半的变换。因此,如果我们将4插入
3N*log(N)+N
,我们得到28。现在我们需要考虑复数问题:一个复数乘法是两个乘法,每个实数分量和虚分量都是一个加法。所以每个复数运算大约相当于3个MAC,我们看到这仍然比直接卷积慢

随着数据量越来越大,FFT方法确实开始发挥作用。如果使用2048个长输入,则操作数为3*10240+1024=34k。即使将复数开销乘以3,这与直接实现的~4M操作相比也非常有利

FFT方法值得考虑的另一种情况是,如果需要将一个数组与多个数组进行卷积,或者将所有数组与所有数组进行卷积。在这种情况下,您可以计算一次输入转换并重用它们。对于K序列,如果需要执行所有K^2交叉卷积,可以执行K变换、K^2复数数组乘法和K^2逆变换。对于输入大小为8的10个数组,这少于1500个复数操作(
10*4*log(4)+500+100*4*log(4)
用于输入、转换乘法和输出)。执行直接方法需要
100*64
MAC,因此FFT方法胜出

但对于成对的情况,一个好的直接实现似乎是轻而易举的赢家。

在“快速傅立叶变换和卷积算法”中,Nussbaumer报告了一种优化方法,使用14次乘法和46次加法计算8项卷积(在实数上)。我怀疑用标准算术能做得更好


我觉得费马/欧拉数变换是相关的,但我无法填写细节。

你能澄清一下“8个无符号19位整数”吗?您的意思是有19个输出值,每个值都是8位数字吗?或者,您的意思是在每个输出样本中最多有19个有效位?还有,你们有一百万双吗?或者你是在比较一个序列和一百万个其他序列?或者你有一百万个序列,你需要所有的交叉卷积吗?@mtrw循环卷积产生8个结果(8 x 255²量级)。假设所有对都是不同的。根据用例的细节,在多核GPU上进行计算可能会产生很大的加速。通用FFT是不可能的,但是对于tiny
N
有优化版本。