如果发生某种情况,是否可以在 SIMD 指令中进行比较并交换值。换句话说,我有 4 个整数:
(100 5) (1 42)
Run Code Online (Sandbox Code Playgroud)
我想收到:
(5 100) (1 42)
Run Code Online (Sandbox Code Playgroud)
即我想成对比较(第一个值与第二个值,第三个值与第四个值),如果左操作数更大 - 交换值。是否可以只使用 1 个 SIMD?
PS:这是我第一次尝试 SIMD,可能我使用了错误的术语 - 如果我错了,请纠正我。
我正在研究并行处理算法以提高处理速度。\n我想测试Agner Fog\ 的矢量类库 VCL。
\n\n我想知道如何选择不同的向量类,例如Vec16c(SSE2 指令集)和Vec32c(AVX 指令集)。
我使用的是 Intel\xc2\xae Atom\xe2\x84\xa2 x5-Z8350 处理器,根据规格,它支持 SSE4.2 指令集。
\n\n如何在硬件支持方面有效选择向量类?\n对于我的处理器,我可以使用 AVX 指令集推荐的 Vec32c 吗?
\n我找到了以下 _m128i 的解决方案
int horizontal_max_Vec4i(__m128i x) {
__m128i max1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(0,0,3,2));
__m128i max2 = _mm_max_epi32(x,max1);
__m128i max3 = _mm_shuffle_epi32(max2, _MM_SHUFFLE(0,0,0,1));
__m128i max4 = _mm_max_epi32(max2,max3);
return _mm_cvtsi128_si32(max4);
}
Run Code Online (Sandbox Code Playgroud)
返回 m128 的最大浮点数的等效函数是什么?
(我可以使用任何版本的SSE和AVX)
将不胜感激任何帮助
我已经知道 SIMD 指令集包含 SSE1 到 SSE5。
不过没找到太多讲什么指令集支持MIMD arch。
在c++代码中,我们可以使用intrinsic来编写“SIMD运行”代码。
有没有办法编写“MIMD运行”代码?
如果 MIMD 比 SIMD 更强大,最好编写支持 MIMD 的 C++ 代码。
我的想法正确吗?
我正在寻找计算以下函数的有效方法:
输入:__m128i data, uint8_t in;
输出:布尔值,指示是否有任何字节data是in。
我基本上是使用它们来为容量为 8 的字节实现空间/时间高效的堆栈。我最有效的解决方案是首先计算__m128i tmp所有字节为 的 a in。然后检查是否有任何字节tmp\xor data是零字节。
我有一个特别的问题。我将尝试尽可能准确地描述这一点。
我正在做一个非常重要的“微优化”。一次运行数天的循环。所以如果我能减少这个循环时间,它需要一半的时间。10 天将减少到只有 5 天等。
我现在拥有的循环是函数:“testbenchmark1”。
我有 4 个索引需要在这样的循环中增加。但是当从列表中访问索引时,实际上需要一些额外的时间,正如我所注意到的。这就是我想知道是否有其他解决方案。
indexes[n]++; //increase correct index
“testbenchmark1”的完整代码需要 122 毫秒:
void testbenchmark00()
{
Random random = new Random();
List<int> indexers = new List<int>();
for (int i = 0; i < 9256408; i++)
{
indexers.Add(random.Next(0, 4));
}
int[] valueLIST = indexers.ToArray();
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int[] indexes = { 0, 0, 0, 0 };
foreach (int n in valueLIST) //Takes 122 ms
{
indexes[n]++; //increase correct index
}
stopWatch.Stop();
MessageBox.Show("stopWatch: " + stopWatch.ElapsedMilliseconds.ToString() …Run Code Online (Sandbox Code Playgroud) 我正在学习和玩 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) 拿这个代码。
#include <stdlib.h>
int main(int argc , char **argv) {
int *x = malloc(argc*sizeof(int));
for (int i = 0; i < argc; ++i) {
x[i] = argc;
}
int t = 0;
for (int i = 0; i < argc; ++i) {
t += x[i];
}
free(x);
return t;
Run Code Online (Sandbox Code Playgroud)
这个循环
for (int i = 0; i < argc; ++i) {
x[i] = argc;
}
Run Code Online (Sandbox Code Playgroud)
向量化为
movdqu xmmword ptr [rax + 4*rdx], xmm0
movdqu xmmword ptr [rax + 4*rdx + 16], …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 16 字节的内存加载到模块中的__m128i类型中std::arch:
#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
use std::arch::x86_64::__m128i;
fn foo() {
#[cfg(all(target_arch = "x86_64", target_feature = "sse2"))]
use std::arch::x86_64::_mm_load_si128;
unsafe {
let mut f: [i8; 16] = [0; 16];
f[0] = 5;
f[1] = 66;
let g = _mm_load_si128(f as *const __m128i);
}
}
fn main() {
foo();
}
Run Code Online (Sandbox Code Playgroud)
我的代码导致错误:
error[E0605]: non-primitive cast: `[i8; 16]` as `*const __m128i`
--> src/main.rs:12:32
|
12 | let g = _mm_load_si128(f as *const __m128i);
| ^^^^^^^^^^^^^^^^^^^ an …Run Code Online (Sandbox Code Playgroud) 我有一个可重现的样本,如下所示 -
#include <iostream>
#include <chrono>
#include <immintrin.h>
#include <vector>
#include <numeric>
template<typename type>
void AddMatrixOpenMP(type* matA, type* matB, type* result, size_t size){
for(size_t i=0; i < size * size; i++){
result[i] = matA[i] + matB[i];
}
}
int main(){
size_t size = 8192;
//std::cout<<sizeof(double) * 8<<std::endl;
auto matA = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
auto matB = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
auto result = (float*) aligned_alloc(sizeof(float), size * size * sizeof(float));
for(int i = …Run Code Online (Sandbox Code Playgroud) simd ×10
c++ ×6
sse ×3
avx ×2
avx2 ×2
gcc ×2
intrinsics ×2
c ×1
c# ×1
clang ×1
histogram ×1
openmp ×1
optimization ×1
performance ×1
rust ×1