Does calling sqrtf always result in a single asm instruction?

I was recently running some performance benchmarks across different platforms to understand the cost of some simple mathematic functions such as sqrtf and quickly noticed, under certain circumstances compilers such as MSVC, Clang and GCC by default will not generate a single x86-64 sqrtss instruction, there is a little more to it…

I think discovering the following is a good example of why it’s always a good idea to inspect the generated assembly code when optimising performance to fully understand what is happening under the hood.

Source code:

#include <math.h>
float square(float num) 
{
    return sqrtf(num);
}

MSVC v19.latest + /O2:

float square(float) PROC
        xorps   xmm1, xmm1
        ucomiss xmm1, xmm0
        ja      SHORT $LN3@square
        sqrtss  xmm0, xmm0
        ret     0
$LN3@square:
        jmp     sqrtf
float square(float) ENDP

So what’s going on here?

Isn’t the sqrtss instruction exactly what we need? We can see it generated in the assembly but there is some additional logic in there plus an actual function call to the sqrtf function on line 8. So lets get a better understanding of what’s happening:

xorps xmm1, xmm1 – Here we are putting a value of zero in to the xmm1 register. xorps is: “Bitwise Logical XOR of Packed Single Precision Floating-Point Values”. It’s common for compilers to generate a value of zero through a simple, fast XOR operation because if you XOR the same value, the result is always zero.

ucomiss xmm1, xmm0 – Next we have a comparison operation. ucomiss: “Unordered Compare Scalar Single Precision Floating-Point Values and Set EFLAGS”. So now we are comparing our input value to the function (xmm0) to zero (xmm1). This operation will set the EFLAGS based on the comparison of the values which will then be used in the following ja operation.

ja SHORT $LN3@square – This is a jump instruction. ja will jump to the specified label if the comparison is above. So in our case, it will jump if the value in xmm0 is above xmm1. So it’s checking if zero is above the value passed to the function. Or to flip this on its head, it’s checking if the value we passed to our function is less than zero.

So if we pass a value less than zero, we’re going to jump to the label $LN3@square: which ends up calling the full sqrtf function. Otherwise we end up calling the sqrtss function and returning.

So why is the logic branching here based on whether a negative value is passed? Let’s start by taking a look at the documentation for the sqrtf function (https://linux.die.net/man/3/sqrtf):

Domain error: x less than -0
errno is set to EDOM. An invalid floating-point exception (FE_INVALID) is raised.

Hmm… Let’s understand the error handling with these functions a little but further…

Math Error

math_error is used for detecting errors from mathematical functions. It’s a feature I’ve not come across before in game development code, most times we call math functions we will sanitise the input before calling the function and we likely won’t be writing code which can gracefully handle the results of a bad value passed to a math function (except perhaps in non-shipping builds).

You can use math error library like below to check the results of a call such as sqrtf:

float safe_sqrtf(float f)
{
    // Always clear errno by calling _set_errno(0) immediately 
    // before a call that may set it, 
    // and check it immediately after the call.
    errno = 0;
    float result = sqrtf(f);
    int error_value = errno;
    if (error_value != 0)
    {
        printf("sqrtf error %i for value: %f\n", error_value, f);
        return 0.0f;
    }
    return result;
}

So if we passed a negative value to our safe_sqrtf function, we can expect errno to be set to EDOM and we can handle this however we like. The return value from sqrtf will be -nan(ind) so here we instead return 0.0f.

Can we omit math errors?

Yes we can! With MSVC we are given different compiler options for floating point operations these are /fp:strict, /fp:precise and /fp:fast. The default option is /fp:precise. It’s important to know that these floating point controls are global and affect more than just how error handing is performed so it’s not always recommended to enable this without careful scrutiny. You can read more about what these options do here: https://learn.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior

Below is the assembly code generated for each of the three options:

/fp:strict

float square(float) PROC
        rex_jmp QWORD PTR __imp_sqrtf
float square(float) ENDP

Here we never use the sqrtss instruction, it always ends up calling the sqrtf implementation.

/fp:precise

float square(float) PROC
        rex_jmp QWORD PTR __imp_sqrtf
float square(float) ENDPfloat square(float) PROC
        xorps   xmm1, xmm1
        ucomiss xmm1, xmm0
        ja      SHORT $LN3@square
        sqrtss  xmm0, xmm0
        ret     0
$LN3@square:
        jmp     sqrtf
float square(float) ENDP

/fp:fast

float square(float) PROC
        sqrtss  xmm0, xmm0
        ret     0
float square(float) ENDP

What about other compilers? With Clang or GCC we can get the same results by passing -ffast-math but this enables a lot of other optimisations and assumptions which in my experience within game development can have a negative impact on gameplay features relying on very precise floating point accuracy. The good news though is that -ffast-math is a big collection of other compiler options and we can just disable math error handling specifically with the following: -fno-math-errno.

Can we do it without compiler options?

Yes! We can use the intrinsic _mm_sqrt_ss which will translate to the exact sqrtss assembly instruction we’ve been aiming for. Lets see how that could look:

Source code:

#include <xmmintrin.h>
__m128 square_mm(__m128 num) 
{
    return _mm_sqrt_ss(num);
}

MSVC v19.latest + /O2:

float square(float) ENDP__m128 square_mm(__m128) PROC
        movups  xmm0, XMMWORD PTR [rcx]
        sqrtss  xmm0, xmm0
        ret     0
__m128 square_mm(__m128) ENDP

Hmm, that’s not as optimal as previous results with the assembly generated! What’s going on here? Under MSVC if we’re expecting to use SIMD registers directly, it’s best to add the __vectorcall to the function. Here is an extract from: https://learn.microsoft.com/en-us/cpp/cpp/vectorcall

The __vectorcall calling convention specifies that arguments to functions are to be passed in registers, when possible. __vectorcall uses more registers for arguments than __fastcall or the default x64 calling convention use. The __vectorcall calling convention is only supported in native code on x86 and x64 processors that include Streaming SIMD Extensions 2 (SSE2) and above.

So lets try it again with __vectorcall added:

Source code:

#include <xmmintrin.h>
__m128 __vectorcall square_mm(__m128 num) 
{
    return _mm_sqrt_ss(num);
}

MSVC v19.latest + /O2:

__m128 square_mm(__m128) PROC
        sqrtss  xmm0, xmm0
        ret     0
__m128 square_mm(__m128) ENDP

So you can see how the explicit __vectorcall now has produced the same instructions as the /fp:fast variant but we’ve done it without global compiler options. I expect there are other options you could explore with pragma’s or function attributes in order to dictate math error functionality for specific sections of code but I have not extensively explored this.

Further SIMD behaviour

If we run some more tests using SIMD, how will the compiler handle it?

4 Float Loop:

Here we have 4 floats passed to a function and a loop where we explicitly call sqrtf() on each of them. The interesting part here is that even with the default /fp:precise behaviour, the compiler automatically omits the negative check and call to the sqrtf C function which is different to the behaviour on a single float.

__m128 __vectorcall m128_sqrtf(__m128 m)
{
    __m128 out;
    for (size_t i = 0; i < 4; i++)
	{
		out.m128_f32[i] = sqrtf(m.m128_f32[i]);
	}
    return out;
}

The assembly produced for the code above with standard /O2 on MSVC is our most optimal outcome:

__m128 m128_sqrtf(__m128) PROC
        sqrtps  xmm0, xmm0
        ret     0

The fp:strict variant here naturally procudes a far more complext result with the loop unrolled to make 4 individual calls to the sqrtf. While the fp:fast variant produces the same code.

3 Float Loop:

This is the same as the test on the left but with a loop of only 3 floats instead with the rest of the setup identical. The differences in the code produced are stark:

__m128 __vectorcall m128_sqrtf(__m128 m)
{
    __m128 out;
    for (size_t i = 0; i < 3; i++)
	{
		out.m128_f32[i] = sqrtf(m.m128_f32[i]);
	}
    return out;
}
__m128 m128_sqrtf(__m128) PROC             
$LN22:
        sub     rsp, 72                    
        movaps  XMMWORD PTR [rsp+48], xmm6
        xorps   xmm1, xmm1
        movaps  xmm6, xmm0
        ucomiss xmm1, xmm6
        ja      SHORT $LN15@m128_sqrtf
        xorps   xmm0, xmm0
        sqrtss  xmm0, xmm6
        jmp     SHORT $LN16@m128_sqrtf
$LN15@m128_sqrtf:
        call    sqrtf
$LN16@m128_sqrtf:
        movaps  xmm1, xmm6
        movss   DWORD PTR out$[rsp], xmm0
        shufps  xmm1, xmm6, 85             
        xorps   xmm0, xmm0
        ucomiss xmm0, xmm1
        ja      SHORT $LN13@m128_sqrtf
        xorps   xmm0, xmm0
        sqrtss  xmm0, xmm1
        jmp     SHORT $LN14@m128_sqrtf
$LN13@m128_sqrtf:
        movaps  xmm0, xmm1
        call    sqrtf
$LN14@m128_sqrtf:
        movss   DWORD PTR out$[rsp+4], xmm0
        xorps   xmm0, xmm0
        shufps  xmm6, xmm6, 170            
        ucomiss xmm0, xmm6
        ja      SHORT $LN11@m128_sqrtf
        xorps   xmm1, xmm1
        sqrtss  xmm1, xmm6
        jmp     SHORT $LN20@m128_sqrtf
$LN11@m128_sqrtf:
        movaps  xmm0, xmm6
        call    sqrtf
        movaps  xmm1, xmm0
$LN20@m128_sqrtf:
        movaps  xmm0, XMMWORD PTR out$[rsp]
        movaps  xmm6, XMMWORD PTR [rsp+48]
        shufps  xmm0, xmm0, 210            
        movss   xmm0, xmm1
        shufps  xmm0, xmm0, 201            
        add     rsp, 72                    
        ret     0
__m128 m128_sqrtf(__m128) ENDP 

I also ran the tests above using a custom struct containing 4 sequential floats rather than the __m128 type to see if this was being handled as a special case but I observed identical behaviour with my custom structure.

Compiler Explorer Examples

View the comparisons of all compilers and their variations on godbolt.org here: https://godbolt.org/z/v3na8z91P

Performance

So lets take a look at the performance difference of our variants… For these tests I have used Google Benchmark: https://github.com/google/benchmark – A great open source tool for benchmarking small sections of code in isolation.

When using a tool like Google Benchmark and testing a very small section of code like I am here with a single function, it’s incredibly important to validate that the actual test you’ve written is being executed as expected. I’m always surprised how clever compilers these days can actually be in how they can completely eliminate and optimise code away.

The key part in the code below is to ensure the variable passed to sqrtf is a volatile, so the compiler is forced to read the value from memory again and cannot make assumptions about its values. Without this, the compiler is clever enough to realise the work done in the loop never changes for each iteration and only invoke sqrtf once in certain situations. We also shouldn’t take the figures here as “the cost of calling”, what we’re interested in here is how much faster each variation is compared to the default.

void BM_sqrtf(benchmark::State& state)
{
	float A = 0.0f;
	volatile float B = 1.0f;

	do_not_optimise(A);
	do_not_optimise(B);

	for (auto _ : state)
	{
		A += sqrtf(B);
	}

	do_not_optimise(A);
	do_not_optimise(B);
}
Test Setup/fp:strict/fp:precise (default)/fp:fast
AMD Ryzen 5 5600X2.76 ns2.63 ns2.63 ns
Intel i5-8265U3.90 ns2.44 ns2.44 ns

So what’s really interesting here is no observable difference between /fp:precise and /fp:fast despite us knowing /fp:fast is a simple sqrtss instruction while /fp:fast has additional logic to check if the value is negative first and then branch based on that. I can’t fully explain the reasons for this but I expect perhaps branch prediction is always taking the correct path with my running the same test over and over with the same values but it’s very interesting how the additional instructions we know are present here do not affect the test results.

Comparing to the /fp:strict variant, we see a performance difference, especially so on my laptop Intel chip, over a 50% performance hit and a far smaller hit on the AMD chip.

Raspberry Pi (ARM64)

I also took the opportunity to run the test on a Raspberry Pi 3 Model B V.2. GCC here does not have the equivalent of the /fp:strict which always generated a jmp instruction so instead the test here is with the default -O3 versus -O3 -fno-math-errno. The tests here were compiled using GCC version 14.2.0.

-O3:

square_root(float):
        fcmp    s0, #0.0
        bpl     .L5
        b       sqrtf
.L5:
        fsqrt   s31, s0
        fmov    s0, s31
        ret

-O3 -fno-math-errno:

square_root(float):
        fsqrt   s0, s0
        ret
Test Setup-O3-O3 -fno-math-errno
Raspberry Pi 3 Model B V.220.1 ns15.9 ns

The comparison on the ARM chip of -O3 vs -O3 -fno-math-errno is the equivalent of /fp:precise and /fp:fast on the MSVC compiler so it’s very interesting that we see a large performance difference here on the ARM and GCC compiler while on the MSVC and x86-64 chips we saw no difference at all. On the Raspberry Pi we observe over a 25% speed improvement by using the -fno-math-errno.

3 Float Loop Performance

I also elected to run some further tests on the setup where we have a loop calling sqrtf three times because this resulted in some large differences with the code produced. The function for this test looks like this:

struct Float3
{
   float f[3];
};
__declspec(noinline) Float3 __vectorcall sqrt_float3_no_inline(Float3 m)
{
	Float3 o;
	for (size_t i = 0; i < 3; i++)
	{
		o.f[i] = sqrtf(m.f[i]);
	}
	return o;
}

Below is the assembly produced for each of the results on MSVC and the performance results on AMD Ryzen 5 5600X. In this test case, we do observe a very small performance improvement between /fp:precise and /fp:fast.

/fp:strict (5.54 ns)

Float3 sqrt_float3_no_inline(Float3) PROC
$LN12:
        push    rbx
        sub     rsp, 80
        movaps  XMMWORD PTR [rsp+64], xmm6
        movaps  xmm6, xmm0
        unpcklps xmm6, xmm1
        movaps  xmm0, xmm6
        movaps  XMMWORD PTR [rsp+48], xmm7
        movd    ebx, xmm2
        call    QWORD PTR __imp_sqrtf
        movaps  xmm7, xmm0
        movaps  xmm0, xmm6
        shufps  xmm0, xmm0, 85
        call    QWORD PTR __imp_sqrtf
        movaps  xmm6, xmm0
        movd    xmm0, ebx
        call    QWORD PTR __imp_sqrtf
        movaps  xmm2, xmm0
        movaps  xmm1, xmm6
        movaps  xmm6, XMMWORD PTR [rsp+64]
        movaps  xmm0, xmm7
        movaps  xmm7, XMMWORD PTR [rsp+48]
        add     rsp, 80
        pop     rbx
        ret     0
Float3 sqrt_float3_no_inline(Float3) ENDP

/fp:precise (3.55 ns)

Float3 sqrt_float3_no_inline(Float3) PROC
$LN21:
        sub     rsp, 88       
        movaps  XMMWORD PTR [rsp+64], xmm6
        xorps   xmm3, xmm3
        ucomiss xmm3, xmm0
        movaps  XMMWORD PTR [rsp+48], xmm7
        movaps  xmm6, xmm1
        movaps  XMMWORD PTR [rsp+32], xmm8
        movaps  xmm7, xmm2
        ja      SHORT $LN15@sqrt_float
        xorps   xmm8, xmm8
        sqrtss  xmm8, xmm0
        jmp     SHORT $LN16@sqrt_float
$LN15@sqrt_float:
        call    sqrtf
        movaps  xmm8, xmm0
$LN16@sqrt_float:
        xorps   xmm0, xmm0
        ucomiss xmm0, xmm6
        ja      SHORT $LN13@sqrt_float
        sqrtss  xmm6, xmm6
        jmp     SHORT $LN14@sqrt_float
$LN13@sqrt_float:
        movaps  xmm0, xmm6
        call    sqrtf
        movaps  xmm6, xmm0
$LN14@sqrt_float:
        xorps   xmm0, xmm0
        ucomiss xmm0, xmm7
        ja      SHORT $LN11@sqrt_float
        xorps   xmm0, xmm0
        sqrtss  xmm0, xmm7
        jmp     SHORT $LN12@sqrt_float
$LN11@sqrt_float:
        movaps  xmm0, xmm7
        call    sqrtf
$LN12@sqrt_float:
        movaps  xmm7, XMMWORD PTR [rsp+48]
        movaps  xmm2, xmm0
        movaps  xmm0, xmm8
        movaps  xmm1, xmm6
        movaps  xmm8, XMMWORD PTR [rsp+32]
        movaps  xmm6, XMMWORD PTR [rsp+64]
        add     rsp, 88  
        ret     0
Float3 sqrt_float3_no_inline(Float3) ENDP

/fp:fast (3.36 ns)

Float3 sqrt_float3_no_inline(Float3) PROC
        sqrtss  xmm0, xmm0
        sqrtss  xmm1, xmm1
        sqrtss  xmm2, xmm2
        ret     0
Float3 sqrt_float3_no_inline(Float3) ENDP

Closing thoughts

I started writing this post because I noticed additional complexity when calling sqrtf and it’s led me down a bit of a rabbit hole! But it’s been an interesting journey. The things I’ve taken away from this are:

  • Math.h functions can internally set errno to help diagnose when bad values are passed to them. Disabling this functionality can produce faster and simpler code.
  • Compiler options such as -ffast-math are not all or nothing and contain many individual compiler options so we can select safe ones without unwanted side effects.
  • This little experiment reinforces that you’ve always got to measure performance and you can’t make assumptions about how things will perform on different hardware or platforms. Additionally it’s shown me that using tools such as Google Benchmark, you need to be so careful in the code to write that your compiler will not optimise away your intentions. Don’t underestimate the compiler!

59 responses to “Does calling sqrtf always result in a single asm instruction?”

  1. Medical topics are widely shared and consumed today.Yet availability does not always translate into understanding.Precision is often replaced by generalization.Important background is frequently omitted.Uncertainty often replaces confidence.Most people are actively seeking understanding.Physiological systems respond differently under similar conditions.Understanding emerges over time, not instantly.Because of this, careful observation becomes essential.Discussion connects evidence with lived experience.Longer conversations support nuance.Expert perspectives can be explored calmly.Questions are explored, not rushed.Perspective remains central.For those interested in nuanced discussion.To continue this exploration, learn more about suhagra force 50 mg.

  2. This website features a large amount of engaging and practical information.
    Visitors are able to access content on various subjects.
    All materials are well-structured and simple to navigate.
    The site gets frequent updates with new materials.
    https://atlasproontv.us/product/abonnement-iptv-stream-player-12-mois/
    This makes it a useful destination for everyday use.
    Whether you are looking for quick answers or in-depth insights, the platform covers a wide range.
    The information comes in a accessible and user-friendly format.
    Overall, this site continues to be helpful for a wide audience.

  3. Forestzossy

    BE THE PARTICULAR WINNER OF IPHONE 17 PRO MAX https://telegra.ph/FINAL-5-SLOTS-LEFT-FOR-TONIGHTS-MEGA-DRAW–Ticket-328038-02-06

    EVENT ID: q0ym2u5t1e4i9y1zu2tj9m9l3u0z2w9tf3ob3v5s9g8y0l2qb0io9k6u9q5z8j3le6mc8o8l3p4u3z1bk3yp1p2t5n1z7p9kw3ld4x8z1j5s4r1w

  4. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ВНЖ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ странС ΠΈΠΌΠ΅Π΅Ρ‚ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ΅ прСимущСство.
    Оно прСдоставляСт ΠΏΡ€Π°Π²ΠΎ Π½Π° постоянноС ΠΏΡ€Π΅Π±Ρ‹Π²Π°Π½ΠΈΠ΅ Π² Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠΉ Π΄Π΅Ρ€ΠΆΠ°Π²Π΅.
    граТданство Π·Π° ΠΈΠ½Π²Π΅ΡΡ‚ΠΈΡ†ΠΈΡŽ Π² самотыки
    Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ доступ ΠΊ Π½Π°Ρ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌΡƒ Π·Π΄Ρ€Π°Π²ΠΎΠΎΡ…Ρ€Π°Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°Π½ΠΈΡŽ ΠΈ ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΡŽ.
    НаличиС ВНЖ сущСствСнно ΠΎΠ±Π»Π΅Π³Ρ‡Π°Π΅Ρ‚ процСсс банковского сотрудничСства ΠΈ открытия бизнСса.
    Π’ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ счётС, это являСтся ваТнСйшим этапом ΠΊ постоянному ΠΏΡ€ΠΎΠΆΠΈΠ²Π°Π½ΠΈΡŽ ΠΈΠ»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ граТданству.

  5. Forestzossy

    You are a swiftest time from iPhone 17 Pro Max https://telegra.ph/FINAL-5-SLOTS-LEFT-FOR-TONIGHTS-MEGA-DRAW–Ticket-957424-02-06

    SESSION ID: s2bn3g9y8x7t1r7hw6mh1j2a6m9l9x6uj4ud5v4l5p9k0r4mt9ps0q8t0g7j2m5nc2sx0i4h0j6y8t1vt7yj3f7g9h2n3j7wh5cu2g4i8g5m2n8n

  6. 每ζ—₯AIε·₯ε…·ε―Όθˆͺ

  7. wish you all the best

  8. wish you best and best

  9. ΠΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ новости https://komputer-nn.ru Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΉ: ИИ, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС, смартфоны, ΠΏΠ»Π°Π½ΡˆΠ΅Ρ‚Ρ‹ ΠΈ Π³Π°Π΄ΠΆΠ΅Ρ‚Ρ‹. Π‘Π²Π΅ΠΆΠΈΠ΅ ΠΎΠ±Π·ΠΎΡ€Ρ‹, Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ° ΠΈ Π³Π»Π°Π²Π½Ρ‹Π΅ события IT-сфСры

  10. Π₯ΠΎΡ‡Π΅ΡˆΡŒ ΠΎΠ±ΡƒΡ‡Π°Ρ‚ΡŒΡΡ? складчина сСрвис для поиска Π²Ρ‹Π³ΠΎΠ΄Π½Ρ‹Ρ… ΠΏΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅. ΠŸΠΎΠ»ΡƒΡ‡Π°ΠΉΡ‚Π΅ знания лСгально ΠΈ ΡΠΊΠΎΠ½ΠΎΠΌΡŒΡ‚Π΅ Π½Π° ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΈ

  11. Ralphvoift

    ΡˆΠΊΠ°Ρ„Ρ‹ ΠΏΠΎ ΠΈΠ½Π΄ΠΈΠ²ΠΈΠ΄ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌ москва ΡˆΠΊΠ°Ρ„Ρ‹ ΠΊΡƒΠΏΠ΅ Π½Π° Π·Π°ΠΊΠ°Π· москва

  12. FrankRoW

    ΠŸΡ€Π΅Π΄Π»Π°Π³Π°Π΅ΠΌ ΠΊΡƒΠΏΠΈΡ‚ΡŒ Ρ‰Π΅Π±Π΅Π½ΡŒ https://sheben23.ru ΠΈ пСсок Π² ΠšΡ€Π°ΡΠ½ΠΎΠ΄Π°Ρ€Π΅ с доставкой. Π’ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Π»ΡŽΠ±Ρ‹Π΅ Ρ„Ρ€Π°ΠΊΡ†ΠΈΠΈ щСбня для ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°, Π±Π΅Ρ‚ΠΎΠ½Π° ΠΈ Π΄ΠΎΡ€ΠΎΠ³. ΠšΠ°Ρ‡Π΅ΡΡ‚Π²ΠΎ ΠΏΠΎ Π“ΠžΠ‘Π’. ДоставляСм собствСнными самосвалами быстро ΠΈ Π±Π΅Π· ΠΏΠ΅Ρ€Π΅ΠΏΠ»Π°Ρ‚.

  13. Jameswoumb

    ΠΏΠΎΡ‡ΠΈΡ‚Π°ΠΉ здСсь https://forum-info.ru ΠΌΠ½ΠΎΠ³ΠΎ ΠΎΡ‚Π·Ρ‹Π²ΠΎΠ² ΠΈ историй ΠΎΡ‚ людСй с ΠΏΠΎΡ…ΠΎΠΆΠ΅ΠΉ ситуациСй

  14. JamesNaize

    НуТна ΡΡ‚Π°Π»ΡŒΠ½Π°Ρ Π»Π΅Π½Ρ‚Π°? Π»Π΅Π½Ρ‚Π° ΡΡ‚Π°Π»ΡŒΠ½Π°Ρ упаковочная мягкая ΡˆΠΈΡ€ΠΎΠΊΠΈΠΉ ассортимСнт, Ρ€Π°Π·Π½Ρ‹Π΅ Ρ‚ΠΎΠ»Ρ‰ΠΈΠ½Ρ‹ ΠΈ ΠΌΠ°Ρ€ΠΊΠΈ стали. Π’Ρ‹Π³ΠΎΠ΄Π½Ρ‹Π΅ Ρ†Π΅Π½Ρ‹, быстрая ΠΎΡ‚Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ поставки для производства ΠΈ ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°

  15. Kelvinsidge

    Π–ΡƒΡ€Π½Π°Π» ΠΏΠΎ ΡΡ‚Π°Π½ΠΊΠΎΠΈΠ½ΡΡ‚Ρ€ΡƒΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ https://www.stankoinstrument.su ΠΏΡ€ΠΎΠΌΡ‹ΡˆΠ»Π΅Π½Π½ΠΎΡΡ‚ΠΈ: Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊΠ°, Π½Π°ΡƒΡ‡Π½Ρ‹Π΅ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ практичСскиС Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ для развития отрасли

  16. Richardalies

    Π²Π·ΡΡ‚ΡŒ Π·Π°ΠΉΠΌ 30000 https://buhgalter-uslugi-moskva.ru

  17. Curtiskab

    ΠœΡ–ΡΡŒΠΊΠΈΠΉ ΠΏΠΎΡ€Ρ‚Π°Π» Π’Π°Ρˆ ΠΏΡ€ΠΎΠ²Ρ–Π΄Π½ΠΈΠΊ Ρƒ ΠΆΠΈΡ‚Ρ‚Ρ– ΠšΡ€ΠΈΠ²ΠΎΠ³ΠΎ Π ΠΎΠ³Ρƒ: Π°Ρ„Ρ–ΡˆΠ°, Π½ΠΎΠ²ΠΈΠ½ΠΈ, Π΄ΠΎΠ²Ρ–Π΄Π½ΠΈΠΊ Ρ‚Π° корисні сСрвіси для ΠΌΠ΅ΡˆΠΊΠ°Π½Ρ†Ρ–Π² Ρ‚Π° туристів

  18. Josephepink

    сайт стоматологии москва Π½ΠΎΠΌΠ΅Ρ€ стоматологии

  19. CharlesTaigo

    дизайнСрскиС ΡΠ²Π΅Ρ‚ΠΈΠ»ΡŒΠ½ΠΈΠΊΠΈ ΠΊΡƒΠΏΠΈΡ‚ΡŒ ΠΊΡƒΠΏΠΈΡ‚ΡŒ Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€ΡΠΊΡƒΡŽ Π»ΡŽΡΡ‚Ρ€Ρƒ

  20. svadebnoe agentstvo 407

    ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΡΠ²Π°Π΄ΡŒΠ±Ρƒ Π² москвС ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΡΠ²Π°Π΄ΡŒΠ±Ρ‹ Π² москвС

  21. Vous soulevez Γ  juste titre que les sites homologuΓ©s FR jouissent d’un encadrement que les
    casinos offshore ne peuvent pas assurer.

    My blog post … surfyn.fr

  22. Ronaldagofs

    ЖСнский ΠΏΠΎΡ€Ρ‚Π°Π» https://secretlady.ru ΠΎ красотС, Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΠ΅, ΠΌΠΎΠ΄Π΅ ΠΈ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡΡ…. ΠŸΠΎΠ»Π΅Π·Π½Ρ‹Π΅ совСты, ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΎ стилС ΠΆΠΈΠ·Π½ΠΈ, ΡƒΡ…ΠΎΠ΄Π΅ Π·Π° собой, сСмьС ΠΈ ΠΊΠ°Ρ€ΡŒΠ΅Ρ€Π΅. ΠΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ‚Ρ€Π΅Π½Π΄Ρ‹, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ экспСртов ΠΈ Π²Π΄ΠΎΡ…Π½ΠΎΠ²Π΅Π½ΠΈΠ΅ для соврСмСнных ΠΆΠ΅Π½Ρ‰ΠΈΠ½.

  23. GlennAdamn

    Product research deep-dive: understanding how to find good products to sell on amazon fba means analyzing competition, margins, and demand – avoid saturated categories!

  24. EdwardViomo

    best crypto signals should make trading clearer, not more stressful. Before trusting screenshots, I’d ask for a longer public track record. If a group sends 30 alerts per day with no explanation, it becomes hard to follow. I prefer fewer trades with better setups and proper updates. If not, I skip it without regret.

  25. Warrenjex

    Industry source verified tiktok BC stock backs every recommendation with field data from a real test fleet. The numbers come from accounts running real campaigns, not from theoretical analysis.

  26. Kevincrala

    Marketplace partner buy google ads with spend history runs a 24-hour replacement guarantee on every account in stock. Bulk pricing kicks in at fifty units; agency contracts available on request.

  27. Chrisaduch

    Если Π½ΡƒΠΆΠ΅Π½ Π½Π΅Π΄ΠΎΡ€ΠΎΠ³ΠΎΠΉ аккумулятор https://www.akb24v.ru 24 Π²ΠΎΠ»ΡŒΡ‚Π° для ΠΏΠΎΠ³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠ°, стоит ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Π½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ с ΠΎΠΏΡ‚ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ рСсурсом ΠΈ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎΠΉ ΠΎΡ‚Π΄Π°Ρ‡Π΅ΠΉ. ΠšΡƒΠΏΠΈΡ‚ΡŒ Ρ‚ΡΠ³ΠΎΠ²ΡƒΡŽ Π±Π°Ρ‚Π°Ρ€Π΅ΡŽ 24V ΠΌΠΎΠΆΠ½ΠΎ Π½Π° сайтС, Ρ‚Π°ΠΌ прСдставлСны Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΠΎΠ΄ Ρ€Π°Π·Π½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΈ Ρ‚ΠΈΠΏΡ‹ Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ.

  28. Kennethked

    Π‘ΠΎΠ»ΡŒΡˆΠ΅ Π½Π° нашСм сайтС: https://aromline.ru/index.php?categoryID=276

  29. BryonBum

    All football match canli-skor results online, game schedules, and league standings. Live updates, statistics, and easy access to information about matches and teams from around the world.

  30. RodolfoHub

    Live football scores https://www.canli-futbol.com.az up-to-date schedules, and league tables. Follow matches, check scores online, analyze team standings, and never miss a beat in world football.

  31. GabrielTuh

    Phasmophobia Game 2026 http://www.phasmo-phobia.com/ is a cross-platform horror game supporting PC, PlayStation, Xbox, and VR. Find out the game’s current price, platform list, system requirements, and the latest updates with new maps, events, and gameplay improvements.

  32. Roberttek

    На сайтС https://chernomorskoe.info собраны новости ЧСрноморского ΠΏΠΎΠ±Π΅Ρ€Π΅ΠΆΡŒΡ ΠΈ информация ΠΎ ΠΊΡƒΡ€ΠΎΡ€Ρ‚Π½Ρ‹Ρ… Π³ΠΎΡ€ΠΎΠ΄Π°Ρ… ОдСсской области. Π£Π·Π½Π°Π²Π°ΠΉΡ‚Π΅ ΠΎ событиях, ΠΎΡ‚Π΄Ρ‹Ρ…Π΅ ΠΈ Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠΈ Ρ€Π΅Π³ΠΈΠΎΠ½Π°.

  33. Woodrowraign

    На ΠΏΠΎΡ€Ρ‚Π°Π»Π΅ https://o-remonte.com Π²Ρ‹ Π½Π°ΠΉΠ΄Ρ‘Ρ‚Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΎ Ρ€Π΅ΠΌΠΎΠ½Ρ‚Π΅, Π΄ΠΈΠ·Π°ΠΉΠ½Π΅ ΠΈ ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΡΡ‚Π²Π΅. Π‘Π°ΠΉΡ‚ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΠΏΡ€Π°ΠΊΡ‚ΠΈΡ‡Π½Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ, Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ ΠΈ ΠΈΠ΄Π΅ΠΈ для создания ΡƒΡŽΡ‚Π½ΠΎΠ³ΠΎ пространства.

  34. JamesIdews

    Interested in UFC? https://ufc-white-house.com unique mixed martial arts tournament will take place on June 14, 2026, in Washington, D.C., on the South Lawn of the White House. It will be the first professional sporting event in history to be held directly on the grounds of the U.S. presidential residence.

  35. Jarredtom

    Π’Π΅ΠΌ, ΠΊΡ‚ΠΎ Ρ…ΠΎΡ‡Π΅Ρ‚ Π΄ΠΎΡ€Π°ΠΌΡ‹ Π² Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΌ качСствС Π±Π΅Π· суСты ΠΈ Π΄ΠΎΠ»Π³ΠΈΡ… поисков, DoramaGo Π»Π΅Π³ΠΊΠΎ станСт ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ мСстом для ΡƒΡŽΡ‚Π½ΠΎΠ³ΠΎ просмотра Π² свободноС врСмя. Π—Π΄Π΅ΡΡŒ собраны корСйскиС, китайскиС, японскиС, тайскиС ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ азиатскиС сСриалы, Π³Π΄Π΅ Π΅ΡΡ‚ΡŒ Ρ‚ΠΎ самоС настроСниС, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΡ€Π°ΠΌΡ‹ Ρ‚Π°ΠΊ цСнят: Π½Π΅ΠΆΠ½Ρ‹Π΅ ΠΈ Π΄Ρ€Π°ΠΌΠ°Ρ‚ΠΈΡ‡Π½Ρ‹Π΅ истории, Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚Ρ‹, яркиС Π³Π΅Ρ€ΠΎΠΈ ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½Π°Ρ красота азиатских сСриалов. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ Π²Ρ‹Π±ΠΎΡ€ ΠΏΠΎ Ρ€Π°Π·Π΄Π΅Π»Π°ΠΌ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΈΡΡ‚ΠΎΡ€ΠΈΡŽ ΠΏΠΎΠ΄ настроСниС ΠΏΠΎ странС, ΠΆΠ°Π½Ρ€Ρƒ, Π³ΠΎΠ΄Ρƒ ΠΈΠ»ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠ΅Π½ΠΈΡŽ, Π° рСгулярныС обновлСния ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π΅ ΠΏΡ€ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅.

  36. Keenanlow

    Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ русскиС сСриалы https://top-tvshou.ru ΠΈ Π’Π’-ΡˆΠΎΡƒ ΠΎΠ½Π»Π°ΠΉΠ½ бСсплатно Π² Ρ…ΠΎΡ€ΠΎΡˆΠ΅ΠΌ качСствС. Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ коллСкция популярных ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ², Π½ΠΎΠ²Ρ‹Π΅ сСрии ΠΈ Π»ΡŽΠ±ΠΈΠΌΡ‹Π΅ Ρ‚Π΅Π»Π΅ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ. Π£Π΄ΠΎΠ±Π½Ρ‹ΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³, быстрый поиск ΠΏΠΎ ΠΆΠ°Π½Ρ€Π°ΠΌ ΠΈ Π°ΠΊΡ‚Π΅Ρ€Π°ΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅, ΠΏΠ»Π°Π½ΡˆΠ΅Ρ‚Π΅ ΠΈ смартфонС Π±Π΅Π· рСгистрации.

  37. ΠœΠ΅Π΄ΠΈΡ†ΠΈΠ½ΡΠΊΠΈΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚Π°Π» https://symmed.ru новости здравоохранСния ΠΈ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΎ соврСмСнных ΠΌΠ΅Ρ‚ΠΎΠ΄Π°Ρ… лСчСния: хирургия, ЭКО, ΠΎΡ„Ρ‚Π°Π»ΡŒΠΌΠΎΠ»ΠΎΠ³ΠΈΡ ΠΈ ΠΏΡ€ΠΎΡ„ΠΈΠ»Π°ΠΊΡ‚ΠΈΠΊΠ° Π·Π°Π±ΠΎΠ»Π΅Π²Π°Π½ΠΈΠΉ.

  38. Π˜Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΉ рСсурс https://mcmltd.ru посвящСнный ΡΡ‚Ρ€ΠΎΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ тСхнологиям, ΠΌΠΎΠ½Ρ‚Π°ΠΆΡƒ сэндвич-ΠΏΠ°Π½Π΅Π»Π΅ΠΉ ΠΈ пассивной ΠΎΠ³Π½Π΅Π·Π°Ρ‰ΠΈΡ‚Π΅ мСталлоконструкций с использованиСм спСциализированных систСм Promat.

  39. Dewaynejef

    Π‘Ρ€ΠΎΡ‡Π½ΠΎ Π½ΡƒΠΆΠ½Π° эвакуациия Π°Π²Ρ‚ΠΎ? Π½Π΅Π΄ΠΎΡ€ΠΎΠ³ΠΎ эвакуатор москва Π½Π΅Π΄ΠΎΡ€ΠΎΠ³ΠΎ круглосуточная ΠΏΠΎΠΌΠΎΡ‰ΡŒ Π½Π° Π΄ΠΎΡ€ΠΎΠ³Π΅ ΠΈ быстрая ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ·ΠΊΠ° Π°Π²Ρ‚ΠΎΠΌΠΎΠ±ΠΈΠ»Π΅ΠΉ. Эвакуация Π»Π΅Π³ΠΊΠΎΠ²Ρ‹Ρ… Π°Π²Ρ‚ΠΎ, Π²Π½Π΅Π΄ΠΎΡ€ΠΎΠΆΠ½ΠΈΠΊΠΎΠ², ΠΌΠΎΡ‚ΠΎΡ†ΠΈΠΊΠ»ΠΎΠ² ΠΈ спСцтСхники. ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Π²Ρ‹Π΅Π·Π΄, аккуратная ΠΏΠΎΠ³Ρ€ΡƒΠ·ΠΊΠ° ΠΈ доставка ΠΌΠ°ΡˆΠΈΠ½Ρ‹ Π² любой Ρ€Π°ΠΉΠΎΠ½ Π³ΠΎΡ€ΠΎΠ΄Π° ΠΈ области.

  40. JamesMox

    F1 Direct is a website https://f1-direct.net about the world of Formula 1. Latest news, race results, race calendar, team and driver statistics. Up-to-date information for fans of the royal motor racing world.

  41. ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° послС запоя Ρ†Π΅Π½Π° ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° послС запоя Ρ†Π΅Π½Π°

  42. Ρ€ΡƒΠ»ΠΎΠ½Π½Ρ‹Π΅ ΡˆΡ‚ΠΎΡ€Ρ‹ Π½Π° ΠΎΠΊΠ½Π° Ρ†Π΅Π½Π° https://rulonnye-elektroshtory.ru

  43. Ρ€ΡƒΠ»ΠΎΠ½Π½Ρ‹Π΅ ΡˆΡ‚ΠΎΡ€Ρ‹ с элСктроприводом Ρ†Π΅Π½Π° Ρ€ΡƒΠ»ΠΎΠ½Π½Ρ‹Π΅ ΡˆΡ‚ΠΎΡ€Ρ‹ с элСктроприводом Ρ†Π΅Π½Π°

  44. ΠΏΡ€ΠΎΠΊΠ°ΠΏΠ°Ρ‚ΡŒΡΡ ΠΎΡ‚ алкоголя Π½Π° Π΄ΠΎΠΌΡƒ ΠΏΡ€ΠΎΠΊΠ°ΠΏΠ°Ρ‚ΡŒΡΡ ΠΎΡ‚ алкоголя Π½Π° Π΄ΠΎΠΌΡƒ

  45. ΠΊΠ»ΠΈΠ½ΠΈΠΊΠ° лСчСния зависимостСй ΠΊΠ»ΠΈΠ½ΠΈΠΊΠ° лСчСния зависимостСй

  46. Π½Π°Ρ€ΠΊΠΎΠ»ΠΎΠ³ подростковый Π½Π°Ρ€ΠΊΠΎΠ»ΠΎΠ³ подростковый

  47. Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π°Π»ΠΊΠΎΠ³ΠΎΠ»ΠΈΠ·ΠΌΠ° Π²Ρ‹Π·ΠΎΠ² Π½Π° Π΄ΠΎΠΌ Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π°Π»ΠΊΠΎΠ³ΠΎΠ»ΠΈΠ·ΠΌΠ° Π²Ρ‹Π·ΠΎΠ² Π½Π° Π΄ΠΎΠΌ

  48. ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° ΠΎΡ‚ запоя Π² стационарС ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° ΠΎΡ‚ запоя Π² стационарС

  49. ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° ΠΎΡ‚ запоя ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ ΠΊΠ°ΠΏΠ΅Π»ΡŒΠ½ΠΈΡ†Π° ΠΎΡ‚ запоя ΡΡ‚ΠΎΠΈΠΌΠΎΡΡ‚ΡŒ

  50. Every day is a new beginning

Leave a Reply

Your email address will not be published. Required fields are marked *