相关疑难解决方法(0)

在哪些问题上 SIMD 的性能优于 Cray 式向量?

旨在提供高性能数字运算的 CPU 最终会采用某种向量指令集。基本上有两种:

  1. SIMD。这在概念上很简单,例如,您不仅拥有一组 64 位寄存器及其上的操作,还拥有第二组 128 位寄存器,并且可以同时对两个 64 位值的短向量进行操作。它在实现中变得复杂,因为您还希望可以选择对四个 32 位值进行操作,然后新一代 CPU 提供 256 位向量,这需要一套全新的指令等。

  2. 较旧的 Cray 风格向量指令,其中向量一开始很大,例如 4096 位,但同时操作的元素数量是透明的,并且要在给定操作中使用的元素数量是指令参数。这个想法是,你预先减少一点复杂性,以避免以后出现复杂性。

有人认为选项 2 更好,并且这些论点似乎有道理,例如https://www.sigarch.org/simd-instructions-considered-harmful/

至少乍一看,选项 2 似乎可以完成选项 1 可以做的所有事情,而且更容易,而且总体上更好。

是否存在相反情况的工作负载?SIMD 指令在哪里可以完成 Cray 式向量无法完成的任务,或者可以更快或使用更少的代码完成任务?

simd instruction-set vectorization cpu-architecture

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

通过 avx 指令向量化间接访问

我最近被介绍了向量指令(理论上)并且对如何使用它们来加速我的应用程序感到兴奋。

我想改进的一个方面是一个非常热的循环:

__declspec(noinline) void pleaseVectorize(int* arr, int* someGlobalArray, int* output)
{
    for (int i = 0; i < 16; ++i)
    {
        auto someIndex = arr[i];
        output[i] = someGlobalArray[someIndex];
    }

    for (int i = 0; i < 16; ++i)
    {
         if (output[i] == 1)
         {
             return i;
         }
    }

    return -1;
}
Run Code Online (Sandbox Code Playgroud)

但是,当然,所有 3 个主要编译器(msvc、gcc、clang)都拒绝对此进行矢量化。我可以理解为什么,但我想得到确认。

如果我必须手动矢量化它,它将是:

(1) VectorLoad "arr", 这带来了 16 个 4 字节整数,让我们说到 zmm0

(2) 16个内存从zmm0[0..3]指向的地址加载到zmm1[0..3],从zmm0[4..7]指向的地址加载到zmm1[4..7]所以等等

(3)比较zmm0和zmm1

(4) 向量 popcnt 到输出中找出最高有效位并基本上除以 8 得到匹配的索引

首先,向量指令可以做这些事情吗?就像他们可以执行这种“收集”操作,即从指向 zmm0 的地址加载?

以下是 clang 生成的内容:

0000000000400530 …
Run Code Online (Sandbox Code Playgroud)

c++ simd vectorization compiler-optimization avx512

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

转换位数组以更快地设置

输入是存储在连续存储器中的比特阵列,每1比特存储器具有1比特的比特阵列.

输出是比特阵列的设定位索引的数组.

例:

bitarray: 0000 1111 0101 1010
setA: {4,5,6,7,9,11,12,14}
setB: {2,4,5,7,9,10,11,12}
Run Code Online (Sandbox Code Playgroud)

获得A组或B组都可以.该集存储为uint32_t数组,因此该集的每个元素都是数组中的无符号32位整数.

如何在单个cpu核心上快5倍左右?

当前代码:

#include <iostream>
#include <vector>
#include <time.h>

using namespace std;

template <typename T>
uint32_t bitarray2set(T& v, uint32_t * ptr_set){
    uint32_t i;
    uint32_t base = 0;
    uint32_t * ptr_set_new = ptr_set;
    uint32_t size = v.capacity();
    for(i = 0; i < size; i++){
        find_set_bit(v[i], ptr_set_new, base);
        base += 8*sizeof(uint32_t);
    }
    return (ptr_set_new - ptr_set);
}

inline void find_set_bit(uint32_t n, uint32_t*& ptr_set, uint32_t base){
    // Find the set bits …
Run Code Online (Sandbox Code Playgroud)

c++ sse bit-manipulation set bitarray

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

什么是在软件中模拟 PDEP 和 PEXT 的快速回退算法?

我想围绕 x86 指令PDEP(并行位存储)PEXT(并行位提取)创建一个包装器。在这些不可用的架构上(并且相应的内在函数也不可用),我需要一个快速的回退实现。

32 位整数的朴素算法如下所示:

constexpr std::uint32_t bit_deposit(std::uint32_t src, std::uint32_t mask) {
    std::uint32_t result = 0;
    for (std::uint32_t src_pos = 0, mask_pos = 0; mask_pos != 32; ++mask_pos) {
        if (mask >> mask_pos & 1) {
            result |= (src >> src_pos++ & 1) << mask_pos;
        }
    }
    return result;
}

static_assert(bit_deposit(0b000, 0b000000) == 0b000000);
static_assert(bit_deposit(0b101, 0b101010) == 0b100010);
static_assert(bit_deposit(0b111, 0b101010) == 0b101010);
Run Code Online (Sandbox Code Playgroud)
constexpr std::uint32_t bit_extract(std::uint32_t src, std::uint32_t mask) {
    std::uint32_t result = 0;
    for (std::uint32_t src_pos = …
Run Code Online (Sandbox Code Playgroud)

c++ optimization x86 bit-manipulation bmi

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

基于 BitMask 在数组中设置值的本质

是否有一个内在函数可以在输入数组中的所有位置设置单个值,其中相应位置在提供的 BitMask 中具有 1 位?

10101010 是位掩码

值为 121

它将设置位置 0,2,4,6 值为 121

c x86 bit-manipulation intel intrinsics

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

从程序员的角度来看,"新"处理器中的"新"是什么

我最近对理解低级计算很感兴趣.据我所知,今天广泛使用的计算机遵循x86/x86-64架构.

据我所知,架构,更具体地说,指令集架构(ISA)是程序员能够向CPU发出的指令集.

第一个问题,ISA是不断发展还是保持不变?

我认为它不断发展(意味着新指令不断被添加/先前的指令被修改?)但是旧的处理器如何能够执行用新指令编写的代码?(它不知道新的指令,但应该能够执行代码,因为它具有x86架构).编译器是处理这个东西还是处理器?基本上,相同的指令集如何能够在所有处理器上运行,无论是旧的还是新的?

最后,除了微体系结构,这不是程序员的关注(如果我错了,请纠正我),程序员在处理新处理器时会看到哪些变化?由于微体系结构的变化,旧的指令可能因为有效的实现而快速运行.但是,是否引入了新的指令以允许以前无法完成的操作?或者之前可以用一堆指令做什么,但现在可以通过硬件的变化来完成一个?新的寄存器?还要别的吗?

它是否完成了 - 如果处理器支持这个新的强大指令以加快执行速度,那么使用新指令,否则回退到较慢的旧指令.如果是,谁实现了这个if - else子句?编译器?如果不是,那会发生什么?

x86 x86-64 processor cpu-architecture micro-architecture

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