Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
C++ 在C+中使用乘法累加指令内联汇编+;_C++_Assembly_Arm_Filtering - Fatal编程技术网

C++ 在C+中使用乘法累加指令内联汇编+;

C++ 在C+中使用乘法累加指令内联汇编+;,c++,assembly,arm,filtering,C++,Assembly,Arm,Filtering,我正在ARM9处理器上实现FIR滤波器,并尝试使用SMLAL指令 最初,我实现了下面的过滤器,它工作得很好,只是这个方法使用了太多的处理能力,无法在我们的应用程序中使用 uint32_t DDPDataAcq::filterSample_8k(uint32_t sample) { // This routine is based on the fir_double_z routine outline by Grant R Griffin // - www.dspguru.com

我正在ARM9处理器上实现FIR滤波器,并尝试使用SMLAL指令

最初,我实现了下面的过滤器,它工作得很好,只是这个方法使用了太多的处理能力,无法在我们的应用程序中使用

uint32_t DDPDataAcq::filterSample_8k(uint32_t sample)
 {
    // This routine is based on the fir_double_z routine outline by Grant R Griffin
    // - www.dspguru.com/sw/opendsp/alglib.htm 
    int i = 0; 
    int64_t accum = 0; 
    const int32_t *p_h = hCoeff_8K; 
    const int32_t *p_z = zOut_8K + filterState_8K;


    /* Cast the sample to a signed 32 bit int 
     * We need to preserve the signdness of the number, so if the 24 bit
     * sample is negative we need to move the sign bit up to the MSB and pad the number
     * with 1's to preserve 2's compliment. 
     */
    int32_t s = sample; 
    if (s & 0x800000)
        s |= ~0xffffff;

    // store input sample at the beginning of the delay line as well as ntaps more
    zOut_8K[filterState_8K] = zOut_8K[filterState_8K+NTAPS_8K] = s;

    for (i =0; i<NTAPS_8K; ++i)
    {
        accum += (int64_t)(*p_h++) * (int64_t)(*p_z++);
    }

    //convert the 64 bit accumulator back down to 32 bits
    int32_t a = (int32_t)(accum >> 9);


    // decrement state, wrapping if below zero
    if ( --filterState_8K < 0 )
        filterState_8K += NTAPS_8K;

    return a; 
} 
uint32\u t ddpdatacq::filterSample\u 8k(uint32\u t sample)
{
//该例程基于Grant R Griffin的fir_double_z例程大纲
//-www.dspguru.com/sw/opendsp/alglib.htm
int i=0;
int64_t累计=0;
常数int32*p\u h=hCoeff\u 8K;
常量int32*p_z=zOut_8K+过滤器状态_8K;
/*将示例强制转换为有符号的32位int
*我们需要保留数字的符号性,所以如果24位
*示例为负数,我们需要将符号位向上移动到MSB并填充数字
*用1来保留2的赞美。
*/
int32_t s=样本;
如果(s&0x800000)
s |=~0xffffff;
//将输入样本存储在延迟线的开头,以及NTAP更多
zOut_8K[filterState_8K]=zOut_8K[filterState_8K+NTAPS_8K]=s;
对于(i=0;i>9);
//减量状态,如果低于零
如果(--filterState_8K<0)
过滤器状态_8K+=NTAPS_8K;
返回a;
} 
我一直试图用内联汇编替换乘法累加,因为GCC即使在打开优化的情况下也不使用MAC指令。我将for循环替换为以下内容:

uint32_t accum_low = 0; 
int32_t accum_high = 0; 

for (i =0; i<NTAPS_4K; ++i)
{
    __asm__ __volatile__("smlal %0,%1,%2,%3;"
        :"+r"(accum_low),"+r"(accum_high)
        :"r"(*p_h++),"r"(*p_z++)); 
} 

accum = (int64_t)accum_high << 32 | (accum_low); 
uint32累计低=0;
int32累积高=0;

对于(i=0;i您使用的是哪个编译器版本?我尝试使用GCC4.4.3使用选项-O3-march=armv5te编译您的纯C代码,它生成了smlal指令。

为什么不使用DSP库?您使用的是哪个编译器版本?我尝试使用选项-O3-march=armv5te和i使用GCC4.4.3编译您的纯C代码t生成了smlal指令。我一直在使用4.3.2。我不知道你可以这样指定-march标志。一旦我添加了它,GCC也生成了我希望的程序集。谢谢!@Nils:将你的评论转化为答案:)似乎大多数求和的产品在不同的调用之间并没有变化。如果你保持一个运行的求和,你可以在每次调用中用适当的增量来更新求和,然后你就不需要汇编程序了。但我当然可能读错了。