相关疑难解决方法(0)

在x86上做水平浮点矢量和的最快方法

你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?

SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?

"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)

floating-point optimization x86 assembly sse

41
推荐指数
4
解决办法
2万
查看次数

使用 __m512 (AVX512) 水平添加

如何使用 512 位 AVX 寄存器中的浮点数有效地执行水平加法(即将单个向量中的项加在一起)?对于 128 和 256 位寄存器,这可以使用 _mm_hadd_ps 和 _mm256_hadd_ps 来完成,但没有 _mm512_hadd_ps。Intel 内在函数指南文档 _mm512_reduce_add_ps。它实际上并不对应于单个指令,但它的存在表明存在一种最佳方法,但它似乎没有在 GCC 最新快照附带的头文件中定义,我找不到它与谷歌。

我认为可以使用 _mm512_shuffle_ps 和 _mm512_add_ps 模拟“hadd”,或者我可以使用 _mm512_extractf32x4_ps 将 512 位寄存器分解为四个 128 位寄存器,但我想确保我不会错过更好的东西。

simd intrinsics avx512

6
推荐指数
1
解决办法
5471
查看次数

用sse累积整数向量

我试图改变这个代码来处理std::vector<int>.

float accumulate(const std::vector<float>& v)
{
 // copy the length of v and a pointer to the data onto the local stack
 const size_t N = v.size();
 const float* p = (N > 0) ? &v.front() : NULL;

 __m128 mmSum = _mm_setzero_ps();
 size_t i = 0;

 // unrolled loop that adds up 4 elements at a time
 for(; i < ROUND_DOWN(N, 4); i+=4)
 {
  mmSum = _mm_add_ps(mmSum, _mm_loadu_ps(p + i));
 }

 // add up single values until all …
Run Code Online (Sandbox Code Playgroud)

c++ x86 sse vector simd

6
推荐指数
2
解决办法
2493
查看次数

SIMD:累积相邻对

我正在学习如何使用 SIMD 内在函数和自动向量化。幸运的是,我正在开发一个有用的项目,它似乎非常适合 SIMD,但对于像我这样的新手来说仍然很棘手。

我正在为计算 2x2 像素平均值的图像编写一个过滤器。我通过将两个像素的总和累加到一个像素中来进行部分计算。

template <typename T, typename U>
inline void accumulate_2x2_x_pass(
  T* channel, U* accum,
  const size_t sx, const size_t sy, 
  const size_t osx, const size_t osy,
  const size_t yoff, const size_t oyoff
) {

  const bool odd_x = (sx & 0x01);

  size_t i_idx, o_idx;

  // Should be vectorizable somehow...
  for (size_t x = 0, ox = 0; x < sx - (size_t)odd_x; x += 2, ox++) {
    i_idx = x + yoff;
    o_idx = ox …
Run Code Online (Sandbox Code Playgroud)

c++ sse simd intrinsics avx

3
推荐指数
1
解决办法
1851
查看次数

AVX2 simd 在更高的优化级别上的性能比标量差

我正在学习和玩 SIMD 函数并编写了一个简单的程序,将它可以在1 秒内运行的向量加法指令的数量与普通标量加法进行比较。我发现 SIMD 在较低的优化级别上表现相对更好,而在较高的优化级别上表现得更差,我想知道我同时使用 MSVC 和 gcc的原因,这是同一个故事。以下结果来自Ryzen 7 CPU。我还在英特尔平台上进行了测试,也几乎是一样的故事。

#include <iostream>
#include <numeric>
#include <chrono>
#include <iterator>
#include <thread>
#include <atomic>
#include <vector>
#include <immintrin.h>
int main()
{
    const auto threadLimit = std::thread::hardware_concurrency() - 1; //for running main() 
    for (auto i = 1; i <= threadLimit; ++i)
    {
        std::cerr << "Testing " << i << " threads: ";
        std::atomic<unsigned long long> sumScalar {};
        std::atomic<unsigned long long> loopScalar {};
        std::atomic<unsigned …
Run Code Online (Sandbox Code Playgroud)

c++ performance gcc simd avx2

1
推荐指数
1
解决办法
162
查看次数

使用 AVX 内在函数对 __m512i 中的 8 位整数求和

AVX512 为我们提供了对__mm512向量中所有单元格求和的内在函数。然而,他们的一些同行却不见了:还没有_mm512_reduce_add_epi8

_mm512_reduce_add_ps     //horizontal sum of 16 floats
_mm512_reduce_add_pd     //horizontal sum of 8 doubles
_mm512_reduce_add_epi32  //horizontal sum of 16 32-bit integers
_mm512_reduce_add_epi64  //horizontal sum of 8 64-bit integers
Run Code Online (Sandbox Code Playgroud)

基本上,我需要MAGIC在以下代码段中实现。

__m512i all_ones = _mm512_set1_epi16(1);
short sum_of_ones = MAGIC(all_ones);
/* now sum_of_ones contains 32, the sum of 32 ones. */
Run Code Online (Sandbox Code Playgroud)

最明显的方法是使用_mm512_storeu_epi8数组元素并将其相加,但这会很慢,而且可能会使缓存无效。我想存在一种更快的方法。

实施的奖励积分_mm512_reduce_add_epi16也是如此。

c x86 simd intrinsics avx

0
推荐指数
1
解决办法
804
查看次数

标签 统计

simd ×5

c++ ×3

intrinsics ×3

sse ×3

x86 ×3

avx ×2

assembly ×1

avx2 ×1

avx512 ×1

c ×1

floating-point ×1

gcc ×1

optimization ×1

performance ×1

vector ×1