<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C++ on icyveins7's blog</title><link>https://icyveins7.github.io/tags/c++/</link><description>Recent content in C++ on icyveins7's blog</description><generator>Hugo</generator><language>en-us</language><copyright>This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.</copyright><lastBuildDate>Mon, 23 Mar 2026 20:00:00 +0800</lastBuildDate><atom:link href="https://icyveins7.github.io/tags/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>Avoid being baited by your printf statements in CUDA kernels</title><link>https://icyveins7.github.io/posts/2026/03/avoid-being-baited-by-your-printf-statements-in-cuda-kernels/</link><pubDate>Mon, 23 Mar 2026 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2026/03/avoid-being-baited-by-your-printf-statements-in-cuda-kernels/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Behaviour of printf on device is not the same as on host!&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;If you&amp;rsquo;re a &lt;code&gt;printf&lt;/code&gt; aficionado like me, then you use &lt;code&gt;printf&lt;/code&gt; for debugging. A lot. In fact I previously wrote a small logger that uses &lt;code&gt;printf&lt;/code&gt; called &lt;a href="https://github.com/icyveins7/spfLogger"&gt;spfLogger&lt;/a&gt;. I do enjoy the flexibility of tuning every single width/precision with a few characters, and it&amp;rsquo;s something I haven&amp;rsquo;t yet seen C++ be able to emulate with as little irritation.&lt;/p&gt;&#10;&lt;blockquote&gt;&#10;&lt;p&gt;I haven&amp;rsquo;t gotten around to writing code using newer &lt;code&gt;std::format&lt;/code&gt; or &lt;code&gt;println&lt;/code&gt; yet, so the jury&amp;rsquo;s out on that.&lt;/p&gt;</description></item><item><title>Iterative algorithms with CUDA</title><link>https://icyveins7.github.io/posts/2025/11/iterative-algorithms-with-cuda/</link><pubDate>Sat, 29 Nov 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/11/iterative-algorithms-with-cuda/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Because not everything can be made un-iterative..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;There&amp;rsquo;s a pretty large class of algorithms that have been developed for CPUs that involve, optimally, an iterative solver.&lt;/p&gt;&#10;&lt;p&gt;Usually, this is defined by some notion of &lt;em&gt;convergence&lt;/em&gt;; some variable is updated, and then at the end of each iteration it is checked to determine whether further iterations are required.&lt;/p&gt;&#10;&lt;p&gt;This is all fine and dandy in CPU-land, but in GPUs this almost always makes the flow awkward.&lt;/p&gt;</description></item><item><title>Stumbling into a sweep line algorithm's edge case</title><link>https://icyveins7.github.io/posts/2025/09/stumbling-into-a-sweep-line-algorithms-edge-case/</link><pubDate>Wed, 10 Sep 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/09/stumbling-into-a-sweep-line-algorithms-edge-case/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Mistakes that you should learn from, lesson 1..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;I recently wrote some code for interval merging. Every leetcoder can probably recite 15 algorithms to do this in their sleep, but I figured it out myself in this case, and in the process fell into an edge case.&lt;/p&gt;&#10;&lt;p&gt;Here&amp;rsquo;s to writing down your mistakes.&lt;/p&gt;&#10;&lt;h1 id="interval-merging"&gt;Interval merging&lt;/h1&gt;&#10;&lt;p&gt;The generic interval merging problem provides you with a list of start/stop pairs which denote individual intervals. Each interval is then to be merged with any other overlapping intervals; an overlap is defined by at least 1 element being shared between 2 intervals.&lt;/p&gt;</description></item><item><title>Some tips for integrating small bits of CUDA code into larger codebases</title><link>https://icyveins7.github.io/posts/2025/08/some-tips-for-integrating-small-bits-of-cuda-code-into-larger-codebases/</link><pubDate>Wed, 13 Aug 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/08/some-tips-for-integrating-small-bits-of-cuda-code-into-larger-codebases/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Some lessons from general C++ come in handy here..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;In some recent work I integrated some CUDA code I developed into a larger existing codebase, written for the CPU. Essentially, my module(s) would accelerate and replace some existing functionality, but was only a small cog in the machine.&lt;/p&gt;&#10;&lt;p&gt;This is likely applicable to many others, so hopefully the lessons I document here will be concisely useful to those who chance upon this post.&lt;/p&gt;</description></item><item><title>AtomicMinFloat; overloading integer-only atomics for floating-point numbers in CUDA</title><link>https://icyveins7.github.io/posts/2025/03/atomicminfloat-overloading-integer-only-atomics-for-floating-point-numbers-in-cuda/</link><pubDate>Sun, 16 Mar 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/03/atomicminfloat-overloading-integer-only-atomics-for-floating-point-numbers-in-cuda/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Convincing you (and myself) that with some minor edits, we can still use atomicMin for floats in CUDA..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;CUDA has a set of atomic functions for &lt;em&gt;safely&lt;/em&gt; updating the same memory address with different threads. There&amp;rsquo;s a whole list of them in the programming guide &lt;a href="https://docs.nvidia.com/cuda/cuda-c-programming-guide/#atomic-functions"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;However, for &lt;code&gt;atomicMin&lt;/code&gt; (and also &lt;code&gt;atomicMax&lt;/code&gt;), there isn&amp;rsquo;t an overload that works with &lt;code&gt;float&lt;/code&gt;s (or &lt;code&gt;double&lt;/code&gt;s , but who uses those in CUDA anyway..). For this discussion we&amp;rsquo;ll just focus on &lt;code&gt;atomicMin&lt;/code&gt;, but all the points we discuss can be inverted to explain &lt;code&gt;atomicMax&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Gotta go (randomly) fast, thrust vs cuRAND</title><link>https://icyveins7.github.io/posts/2025/03/gotta-go-randomly-fast-thrust-vs-curand/</link><pubDate>Mon, 10 Mar 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/03/gotta-go-randomly-fast-thrust-vs-curand/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;How fast can you generate (pseudo-)random numbers on the GPU?&#10;How fast can you generate (pseudo-)random numbers on the GPU?&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;I recently had to answer this question. Well, not exactly this question, but this was a key part of it.&lt;/p&gt;&#10;&lt;p&gt;A quick google search will bring up two common methods (libraries) when trying to do this in CUDA: thrust and cuRAND. Thrust is known to be a lot easier to set up; no need to write the kernel code and nitty gritty details, so I started with that.&lt;/p&gt;</description></item><item><title>When circumstances don’t allow you to use unique_ptr</title><link>https://icyveins7.github.io/posts/2025/02/when-circumstances-dont-allow-you-to-use-unique_ptr/</link><pubDate>Sun, 23 Feb 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/02/when-circumstances-dont-allow-you-to-use-unique_ptr/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Some background on my single header file memory manager and why I made it..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Picture this. You are working on a codebase with some &lt;del&gt;lazy&lt;/del&gt; &lt;del&gt;inept&lt;/del&gt; questionable decisions from external forces. You are given a class to work on. For the purposes of this post let’s call it &lt;code&gt;MyClass&lt;/code&gt;.&lt;/p&gt;&#10;&lt;p&gt;The class will have its methods invoked in the following order:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;code&gt;MyClass()&lt;/code&gt; i.e. the constructor.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;setup(…)&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;run(…)&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;teardown()&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Repeat 2-4 many times.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;~MyClass()&lt;/code&gt; i.e. the destructor.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;This class will be reused in multiple different scenarios repeatedly, with different input data.&lt;/p&gt;</description></item><item><title>Cross-platform trigonometric SIMD and how the C ABI confused me</title><link>https://icyveins7.github.io/posts/2025/01/cross-platform-trigonometric-simd-and-how-the-c-abi-confused-me/</link><pubDate>Thu, 30 Jan 2025 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2025/01/cross-platform-trigonometric-simd-and-how-the-c-abi-confused-me/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;My small journey in discovering libmvec functions and the C problems I encountered..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;I was recently working on making an existing Windows-only library of SIMD functions cross-platform i.e. making everything work in Linux. Here I&amp;rsquo;m going to highlight some problems I encountered in the process; hopefully it will help someone if they encounter something similar too.&lt;/p&gt;&#10;&lt;h1 id="the-windows-msvc-function"&gt;The Windows (MSVC) function&lt;/h1&gt;&#10;&lt;p&gt;Intrinsics are usually tied to compiler implementations. The one that gave me issues was a bunch of trigonometric functions. Let&amp;rsquo;s use the SSE version that works on floats; in MSVC this was implemented as a simple&lt;/p&gt;</description></item><item><title>Esoteric Errors: 'hidden symbol is referenced by DSO'</title><link>https://icyveins7.github.io/posts/2024/10/esoteric-errors-hidden-symbol-is-referenced-by-dso/</link><pubDate>Fri, 18 Oct 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/10/esoteric-errors-hidden-symbol-is-referenced-by-dso/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Hidden linkage isn&amp;rsquo;t something I&amp;rsquo;d encountered until now, so maybe this will help someone else too..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h1 id="a-new-series-of-posts"&gt;A new series of posts&lt;/h1&gt;&#10;&lt;p&gt;I recently started work on a new codebase - one that is very large and has multiple moving components, from a frontend desktop UI (not my business) to the hardware interface (also not my business) and the backend processing (this one&amp;rsquo;s my business).&lt;/p&gt;&#10;&lt;p&gt;The standard build process had been setup on a remote server, and most people were ok with the process of connecting to it with tangible amounts of latency, but I was not. So my stubborn ass decided to figure out how to build it myself on a local machine. In the process, I encountered a ridiculous number of build errors; they were using custom Makefiles, but they had been generated by some other tool (possibly from Windows, even though it was being built in Linux, since there was a Windows VS solution as well).&lt;/p&gt;</description></item><item><title>Who knew a simple logger class would be this complicated?</title><link>https://icyveins7.github.io/posts/2024/09/who-knew-a-simple-logger-class-would-be-this-complicated/</link><pubDate>Mon, 09 Sep 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/09/who-knew-a-simple-logger-class-would-be-this-complicated/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Writing a printf-based C++ logger class was more of a journey than I originally thought..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;I recently had to work with a codebase where the build process was so convoluted it couldn’t be run and debugged from within a Visual Studio instance, &lt;em&gt;despite being a Visual Studio solution&lt;/em&gt;.&lt;/p&gt;&#10;&lt;p&gt;This was primarily because it had a bunch of Java components, which were mainly used for the UI, and that prevented it from being run as a standard C++ application within the debugger (or maybe you could? I couldn’t find a way..)&lt;/p&gt;</description></item><item><title>Some notes on 2D real-to-complex Fourier transforms</title><link>https://icyveins7.github.io/posts/2024/07/some-notes-on-2d-real-to-complex-fourier-transforms/</link><pubDate>Mon, 15 Jul 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/07/some-notes-on-2d-real-to-complex-fourier-transforms/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;IPP in particular has some very niche ways of packing R2C DFT output, but otherwise there&amp;rsquo;s a few pointers here to keep in mind for how they are implemented in most libraries.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;It&amp;rsquo;s pretty well known that the output of a Fourier transform of real inputs has symmetric properties. This is due to the fact that real waves consist of two conjugate pairs of complex exponentials.&lt;/p&gt;&#10;&lt;p&gt;What may be a bit less obvious (at least to me, when examining some programming libraries) is exactly how many useful output elements there are, and under which scenarios. In particular, I looked at IPP (which has some special packed structure), and cuFFT/NumPy/SciPy (which follow the FFTW structure I think).&lt;/p&gt;</description></item><item><title>CRTP, method chaining, and static polymorphism</title><link>https://icyveins7.github.io/posts/2024/05/crtp-method-chaining-and-static-polymorphism/</link><pubDate>Sat, 04 May 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/05/crtp-method-chaining-and-static-polymorphism/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Yes, it&amp;rsquo;s yet another blogpost about CRTP and how it&amp;rsquo;d be useful..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h1 id="the-1st-issue-method-chaining"&gt;The 1st issue: method chaining&lt;/h1&gt;&#10;&lt;p&gt;Have you seen a billion other blogposts about CRTP? Yes, so have I. But maybe there&amp;rsquo;s a reason for all of them; it wasn&amp;rsquo;t really apparent when reading them previously why it would be useful and/or why I would ever need it.&lt;/p&gt;&#10;&lt;p&gt;But recently, while writing some simple templated code for &lt;a href="https://github.com/icyveins7/ufl"&gt;&lt;code&gt;ufl&lt;/code&gt;&lt;/a&gt;, I had the bright idea of trying to make method chaining possible for the class. That&amp;rsquo;s when my templated class and its derived friend implementation started to fall apart. I fixed this by using CRTP for the first time.&lt;/p&gt;</description></item><item><title>Clang and Eigen's alternatives to complex multiplication SIMD</title><link>https://icyveins7.github.io/posts/2024/03/clang-and-eigens-alternatives-to-complex-multiplication-simd/</link><pubDate>Mon, 11 Mar 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/03/clang-and-eigens-alternatives-to-complex-multiplication-simd/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Clang isn&amp;rsquo;t much better than MSVC for complex number multiplication, while Eigen is equivalent to GCC but uses slightly different instructions.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h1 id="complex-number-multiplication-is-probably-not-common-enough"&gt;Complex Number Multiplication Is Probably Not Common Enough&lt;/h1&gt;&#10;&lt;p&gt;I think I might have bashed MSVC too much on the last post; trying to vectorise our simple 4-element complex number multiplication using clang with AVX instructions delivers &lt;a href="https://godbolt.org/z/35dGqTfKv"&gt;similarly poor results&lt;/a&gt;:&lt;/p&gt;&#10;&lt;pre tabindex="0"&gt;&lt;code&gt;#include &amp;lt;complex&amp;gt;&#10;&#10;void cmul(&#10; const std::complex&amp;lt;float&amp;gt;* __restrict__ x,&#10; const std::complex&amp;lt;float&amp;gt;* __restrict__ y,&#10; std::complex&amp;lt;float&amp;gt;* __restrict__ z&#10;){&#10; for (int i = 0; i &amp;lt; 4; ++i)&#10; z[i] = x[i] * y[i];&#10;}&#10;&#10;void mul(&#10; const float* __restrict__ x,&#10; const float* __restrict__ y,&#10; float* __restrict__ z&#10;){&#10; for (int i = 0; i &amp;lt; 8; ++i)&#10; z[i] = x[i] * y[i];&#10;}&#10;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;cmul(std::complex&amp;lt;float&amp;gt; const*, std::complex&amp;lt;float&amp;gt; const*, std::complex&amp;lt;float&amp;gt;*): # @cmul(std::complex&amp;lt;float&amp;gt; const*, std::complex&amp;lt;float&amp;gt; const*, std::complex&amp;lt;float&amp;gt;*)&#10; vmovsd xmm0, qword ptr [rdi] # xmm0 = mem[0],zero&#10; vmovsd xmm1, qword ptr [rsi] # xmm1 = mem[0],zero&#10; vbroadcastss xmm2, xmm0&#10; vmovshdup xmm0, xmm0 # xmm0 = xmm0[1,1,3,3]&#10; vshufps xmm3, xmm1, xmm1, 225 # xmm3 = xmm1[1,0,2,3]&#10; vmulps xmm0, xmm3, xmm0&#10; vfmaddsub231ps xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm2) +/- xmm0&#10; vmovlps qword ptr [rdx], xmm0&#10; vmovsd xmm0, qword ptr [rdi + 8] # xmm0 = mem[0],zero&#10; vmovsd xmm1, qword ptr [rsi + 8] # xmm1 = mem[0],zero&#10; vbroadcastss xmm2, xmm0&#10; vmovshdup xmm0, xmm0 # xmm0 = xmm0[1,1,3,3]&#10; vshufps xmm3, xmm1, xmm1, 225 # xmm3 = xmm1[1,0,2,3]&#10; vmulps xmm0, xmm3, xmm0&#10; vfmaddsub231ps xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm2) +/- xmm0&#10; vmovlps qword ptr [rdx + 8], xmm0&#10; vmovsd xmm0, qword ptr [rdi + 16] # xmm0 = mem[0],zero&#10; vmovsd xmm1, qword ptr [rsi + 16] # xmm1 = mem[0],zero&#10; vbroadcastss xmm2, xmm0&#10; vmovshdup xmm0, xmm0 # xmm0 = xmm0[1,1,3,3]&#10; vshufps xmm3, xmm1, xmm1, 225 # xmm3 = xmm1[1,0,2,3]&#10; vmulps xmm0, xmm3, xmm0&#10; vfmaddsub231ps xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm2) +/- xmm0&#10; vmovlps qword ptr [rdx + 16], xmm0&#10; vmovsd xmm0, qword ptr [rdi + 24] # xmm0 = mem[0],zero&#10; vmovsd xmm1, qword ptr [rsi + 24] # xmm1 = mem[0],zero&#10; vbroadcastss xmm2, xmm0&#10; vmovshdup xmm0, xmm0 # xmm0 = xmm0[1,1,3,3]&#10; vshufps xmm3, xmm1, xmm1, 225 # xmm3 = xmm1[1,0,2,3]&#10; vmulps xmm0, xmm3, xmm0&#10; vfmaddsub231ps xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm2) +/- xmm0&#10; vmovlps qword ptr [rdx + 24], xmm0&#10; ret&#10;mul(float const*, float const*, float*): # @mul(float const*, float const*, float*)&#10; vmovups ymm0, ymmword ptr [rsi]&#10; vmulps ymm0, ymm0, ymmword ptr [rdi]&#10; vmovups ymmword ptr [rdx], ymm0&#10; vzeroupper&#10; ret&#10;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Compiled with clang 18.1.0, with &lt;code&gt;-O3 -ffast-math -march=x86-64-v3&lt;/code&gt;, this still refuses to vectorise the &lt;code&gt;cmul&lt;/code&gt; function correctly, only using the &lt;code&gt;xmm&lt;/code&gt; registers. I included the normal real-valued float multiplication to check that clang is indeed able to vectorise that. Note that you still need the &lt;code&gt;__restrict__&lt;/code&gt; keywords for the vectorisation to work. Using &lt;code&gt;-ffast-math&lt;/code&gt; doesn&amp;rsquo;t seem to do anything for us in the real float vectorisation, but it does make the complex-valued vectorisation less verbose.&lt;/p&gt;</description></item><item><title>MSVC's terrible auto-vectoriser for AVX</title><link>https://icyveins7.github.io/posts/2024/02/msvcs-terrible-auto-vectoriser-for-avx/</link><pubDate>Sat, 24 Feb 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/02/msvcs-terrible-auto-vectoriser-for-avx/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;MSVC has extremely lackluster auto-vectorisation, so I handrolled intrinsic calls by backtranslating GCC&amp;rsquo;s output.&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;h1 id="the-motivation"&gt;The Motivation&lt;/h1&gt;&#10;&lt;p&gt;I recently decided I wanted to spend some time understanding intrinsics and SIMD at a deeper level.&lt;/p&gt;&#10;&lt;p&gt;In developing code for my project &lt;a href="https://github.com/icyveins7/ffs"&gt;&lt;code&gt;ffs&lt;/code&gt;&lt;/a&gt;, I wanted to make sure that the code was running with at least AVX instructions (because that&amp;rsquo;s my target architecture, and honestly very few computers don&amp;rsquo;t have AVX these days..).&lt;/p&gt;&#10;&lt;p&gt;This led me down a path of discovery; first I discovered the amazing-ness that is &lt;a href="https://godbolt.org"&gt;godbolt.org&lt;/a&gt;, then I joined their discord, where I then asked for some help with understanding basic .asm compiler output.&lt;/p&gt;</description></item><item><title>Getting IPP to work on non-Intel chips</title><link>https://icyveins7.github.io/posts/2024/02/getting-ipp-to-work-on-non-intel-chips/</link><pubDate>Mon, 19 Feb 2024 20:00:00 +0800</pubDate><guid>https://icyveins7.github.io/posts/2024/02/getting-ipp-to-work-on-non-intel-chips/</guid><description>&lt;blockquote&gt;&#10;&lt;p&gt;Intel Performance Primitives is not guaranteed to work on non-Intel chips, but there are some ways around it..&lt;/p&gt;&#10;&lt;/blockquote&gt;&#10;&lt;p&gt;Over the last year or so I&amp;rsquo;ve written a C++ wrapper of header-only templates around a library known as Intel Performance Primitives (IPP). I often use this for its signal processing library, which is - at least by my measurements - one of the fastest, if not the fastest one around. It also has the benefit of having almost everything I need in one place: FFT/DFTs, math array processing, low-pass filtering etc. You can see my templates at the &lt;a href="https://github.com/icyveins7/ipp_ext"&gt;&lt;code&gt;ipp_ext&lt;/code&gt;&lt;/a&gt; repository.&lt;/p&gt;</description></item></channel></rss>