How to make my difference equation make the deadline constraint?
A few general suggestions first:


Recommend using defined types for your declarations, e.g. uint32_t rather than int for U_i. The u in uint32_t stands for unsigned, and I assume you're not using a bipolar ADC. These allow portability across different architectures, as int is compiler dependent.
short is also compiler dependent, it's only guaranteed to be at least 16bits wide. The natural width for an Arm micro is 32bit, so you might get better performance using uint32_t adcValue. Again, compiler dependent, I'm not sure how the M4 handles packing two 16bit values into a single 32bit value.
Your two loops are identical, so just manipulate the indexing to select between the top and bottom.
There are often optimisations to be done if you use powers of 2 for the number of iterations. Can you work on 1024 samples rather than 1000?


To run your loop faster, consider this fixed point approach. Your microcontroller has:


A 12bit ADC
A 12bit DAC


We can represent this in something similar Q12 format (1 integer bit, and 12 fractional), but we'll just normalise things and say 1 &gt; MAX(ADC) &gt;= 0. This means the integer bit is implicitly zero and we will treat all the bits as fractional. When you do a multiplication of a Qm and a Qn fixed point, the product is in Q(m+n) format; we can handle this later. To convert your floating point coefficients to Q12 simply multiply them by \$2^{12}\$. Your coefficients therefore map as:


0.3957 -> 0x0000_0654
0.7914 -> 0x0000_0CA9
0.384  -> 0x0000_0624
0.1979 -> 0x0000_032A


When you multiply your ADC values with these coefficients, you implicitly get a Q24 value out. You can do a right shift by 12 to convert this back to Q12. Your loop now looks something like this:

const uint32_t COEFF_0 = 0x00000654;
const uint32_t COEFF_1 = 0x00000CA9;
const uint32_t COEFF_2 = 0x00000624;
const uint32_t COEFF_3 = 0x0000032A;

for (uint32_t idx = 0; idx &lt; 1024; idx++) {
    U_i[2] = U_i[1];
    U_i[1] = U_i[0];
    U_i[0] = adcValues[idx];
    Y_i[2] = Y_i[1];
    Y_i[1] = Y_i[0];
    Y_i[0] = COEFF_0 * U_i[0] + COEFF_1 * U_i[1] + COEFF_0 * U_i[2] - COEFF_2 * Y_i[1] - COEFF_3 * Y_i[2];
    DAC1-&gt;DHR12R1 = Y_i[0] &gt;&gt; 12;
}


Each iteration through the loop is now (naively estimating) something like 6 assignments and 5 multiply-accumulates (which I believe is a single instruction, MLA). As an estimate, let's say 20 instructions per iteration - even at the 4 MHz clock rate you've quoted, that's about 5 ms for 1000 samples. Hope that's helpful!

Addition

I've put some code up on Godbolt, you can play with the compiler options there. It produces roughly what I expected, around 35 instructions per iteration. It shuffles things around registers a bit more than necessary, so it would be a good exercise for you to understand that and perhaps tighten it up by writing the assembly. Try changing the compiler options; for example, swapping -march=armv7-m for -mcpu=cortex-m4.

You said the time is around 25 ms to do all the samples - the accesses to memory and the DAC will slow things down so the rough estimate of time is of the right order of magnitude. I would anticipate that the write to the DAC register takes a relatively long time. Speeding up your clock will certainly make it run faster, and really with something as capable as an M4, you should be running much faster than 4 MHz.