标签: simd

SIMD内在函数和指针

我已经读过有关将C / C ++内在类型用于SIMD功能(如MMX和SSE)的所有内容,这些都表明您应该将它们用作不透明类型,而不是直接引用内部结构。

但是,当我看许多示例时,它们的工作方式是(指向)原始数据的指针(明确对齐),然后在进行工作之前将它们重新解释为内部类型的指针。但是,通过使用指向内部类型的指针,尤其是在将其他数据作为这些类型的别名时,您是否没有违反该规则?

c c++ simd intrinsics

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

SIMD内在函数 - 它们可以在gpus上使用吗?

我想知道我是否可以在GPU代码中使用SIMD内在函数,如CUDA内核或openCL代码.那可能吗?

c++ cuda simd opencl

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

AltiVec vec_ld()仅适用于16字节对齐变量吗?

在gcc 4.1.2中,vec_ld()在CPU MPC74XX板上不能正常工作。

float temp[4];
__vector float Src;
Src = (__vector float)vec_ld(0, temp);
Run Code Online (Sandbox Code Playgroud)

但是,如果float变量对齐到16个字节,则它可以正常工作:

float temp[4] __attribute__((aligned(16)));
Run Code Online (Sandbox Code Playgroud)

这是设计使然吗?

c powerpc simd altivec

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

SSE - AVX从double转换为char

我想将双精度值的向量转换为char.我必须制作两种不同的方法,一种用于SSE2,另一种用于AVX2.

我开始使用AVX2.

__m128i sub_proc(__m256d& in)
{
    __m256d _zero_pd = _mm256_setzero_pd();

    __m256d ih_pd = _mm256_unpackhi_pd(in,_zero_pd);
    __m256d il_pd = _mm256_unpacklo_pd(in,_zero_pd);

    __m128i ih_si = _mm256_cvtpd_epi32(ih_pd);
    __m128i il_si = _mm256_cvtpd_epi32(il_pd);

    ih_si = _mm_shuffle_epi32(ih_si,_MM_SHUFFLE(3,1,2,0));
    il_si = _mm_shuffle_epi32(il_si,_MM_SHUFFLE(3,1,2,0));

    ih_si = _mm_packs_epi32(_mm_unpacklo_epi32(il_si,ih_si),_mm_unpackhi_epi32(il_si,ih_si));

    return ih_si;
}

__m128i proc(__m256d& in1,__m256d& in2)
{
      __m256d _zero_pd = _mm_setzeros_pd();

      __m128i in1_si = sub_proc(in1);
      __m128i in2_si = sub_proc(in2);

      return _mm_packs_epi16(in1_si,in2_si);
}
int main()
{

double input[32] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32};

char output[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

char check[8];    

double* ibeg = input;
char* obeg = output;

for(int …
Run Code Online (Sandbox Code Playgroud)

c++ simd avx sse2 avx2

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

32位8位比较形成32位汉明字符串

我正在对每个像素执行32次比较的图像执行人口普查变换.我可以有效地生成一个0x0100010100010100的256位向量...其中每个8位对应于0x00或0x01.该载体在下面标识为"比较".我需要折叠这个256位向量来生成一个32位的汉明字符串.数组'census'是我存储8位比较的地方.请注意,此时我并不关心汉明距离,我只对尽快生成字符串感兴趣.我有AVX2可供我使用.我目前的代码:

uint8_t* census = (uint8_t*) _mm_malloc(sizeof(int)*8,32);

...

_mm256_storeu_si256((__m256i*) census, comparisons);

uint32_t hammingString = (uint32_t) (census[0] +
                                    (census[1] << 1)   +
                                    (census[2] << 2)   +
                                    ...
                                    (census[31] << 31));
Run Code Online (Sandbox Code Playgroud)

c c++ sse simd avx

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

数据在C联合中的位置是否有任何标准?

我有以下联盟:

union problem {
    int i;
    int *v;
};
Run Code Online (Sandbox Code Playgroud)

在我的系统上int是4个字节,int*而是8.我有一个数组,其中有10个这样的结构.在某段代码中,我碰巧知道数组的所有成员都使用int了union.我需要将这些int复制到一个int数组中.现在,如果源数组是一个int数组,我可以memcpy用来快速复制数据.

是否可以保证int存储在联合的低或高内存中?我希望能够在不进行迭代的情况下复制数据,因此我在考虑使用SIMD和shuffle进行循环.要做到这一点,我必须知道int实际上在union中的位置,我猜这是特定于实现的.

c arrays simd unions

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

如何在SSE中使用imm8?

我有一个__m128i充满32位整数的寄存器。我想从寄存器中提取第4个元素。

例如,如果

int extract;
__m128i register = _mm_set_epi32(3,2,1,0);
Run Code Online (Sandbox Code Playgroud)

然后我想“提取”值为3。

似乎_mm_extract_epi32()应该可以完成工作。但是,它有一个imm8参数。


图: 在英特尔网站上的描述


我只是不了解imm8工作方式(或者在这种情况下会工作)。有人可以详细说明如何使用imm8作为参数吗?

c++ x86 sse simd visual-studio

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

什么是内在函数的SSE2程序集?

我正在使用Fasm(程序集),我正在寻找这些内在指令的SSE2汇编指令:

_mm_set1_epi8
_mm_cmpeq_epi8
_mm_movemask_epi8
Run Code Online (Sandbox Code Playgroud)

我从哪里得到它们(网站,pdf ......)?

assembly sse simd intrinsics sse2

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

YASM:vmovaps指令导致分段错误

问题:movaps给我一个分段错误.

上下文:x86-64指令vmovaps设计用于Core i系列处理器(我运行此系统)上的AVX寄存器.AVX寄存器的宽度是SSE寄存器的两倍(分别为256和128位).指令vmovaps应将对齐的浮点值(32位)的向量移动到指定的ymm寄存器中.

可能的原因:源数据的对齐特别重要,因为错误对齐的数据是分段错误的来源.但是,即使我对齐了数据,我自己也遇到了分段错误.

    segment .data

align 16
xs:
    dd  0.0
    dd  1.1
    dd  2.2
    dd  3.3
    dd  4.4
    dd  5.5
    dd  6.6
    dd  7.7

align 16
ys:
    dd  8.8
    dd  7.7
    dd  6.6
    dd  5.5
    dd  4.4
    dd  3.3
    dd  2.2
    dd  1.1

    segment .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; Move eight 32-bit floats from "xs" into ymm0
    vmovaps ymm0, [xs]

    ; Move …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 simd nasm avx

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

为什么在CPU上执行线程浮点计算会使它们花费更长的时间?

我目前正在进行科学模拟(引力体)。我首先使用朴素的单线程算法编写了该代码,并且对于少量粒子而言,该代码的性能令人满意。然后,我对该算法进行了多线程处理(令人尴尬的是,它是并行的),程序花了大约3倍的时间。以下是具有相似属性并输出到/ tmp中的文件的琐碎算法的最小,完整,可验证的示例(该示例旨在在Linux上运行,但C ++也是标准的)。请注意,如果您决定运行此代码,它将生成152.62MB的文件。输出数据是为了防止编译器从程序中优化计算。

#include <iostream>
#include <functional>
#include <thread>
#include <vector>
#include <atomic>
#include <random>
#include <fstream>
#include <chrono>

constexpr unsigned ITERATION_COUNT = 2000;
constexpr unsigned NUMBER_COUNT = 10000;

void runThreaded(unsigned count, unsigned batchSize, std::function<void(unsigned)> callback){
    unsigned threadCount = std::thread::hardware_concurrency();
    std::vector<std::thread> threads;
    threads.reserve(threadCount);

    std::atomic<unsigned> currentIndex(0);

    for(unsigned i=0;i<threadCount;++i){
        threads.emplace_back([&currentIndex, batchSize, count, callback]{
            unsigned startAt = currentIndex.fetch_add(batchSize);

            if(startAt >= count){
                return;
            }else{
                for(unsigned i=0;i<count;++i){
                    unsigned index = startAt+i;
                    if(index >= count){
                        return;
                    }
                    callback(index);
                }
            }
        });
    }

    for(std::thread &thread : threads){ …
Run Code Online (Sandbox Code Playgroud)

c++ performance multithreading simd

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

标签 统计

simd ×10

c++ ×6

c ×4

avx ×3

sse ×3

assembly ×2

intrinsics ×2

sse2 ×2

altivec ×1

arrays ×1

avx2 ×1

cuda ×1

multithreading ×1

nasm ×1

opencl ×1

performance ×1

powerpc ×1

unions ×1

visual-studio ×1

x86 ×1

x86-64 ×1