- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想将 double 值 vector 转换为 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 i=0;i<32;i+=8)
{
__m256d in1 = _mm256_loadu_pd(ibeg);
__m256d in2 = _mm256_loadu_pd(ibeg+4);
__m128i tmp = proc(in1,in2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(check),tmp);
std::copy(check,check+8,std::ostream_iterator<int>(std::cout," "));
std::cout<<std::endl;
_mm_storeu_si128(reinterpret_cast<__m128i*>(obeg+i),tmp);
}
}
在此算法结束时,输出包含:
1,2,3,4,0,0,0,0,9,10,11,12,0,0,0,0,17,18,19,20,0,0,0,0,25,26,27,28,0,0,0,0
我的第一个调查显示,如果在函数 proc
中我更改:
return _mm_packs_epi16(in1_si,in2_si);
到:
return _mm_packs_epi16(in2_si,in1_si);
然后输出包含:
5,6,7,8,0,0,0,0,13,14,15,16,0,0,0,0,21,22,23,24,0,0,0,0,29,30,31,31,0,0,0,0
我还没有想出如何打乱 in2_si
的低和高部分。
是否有更好(更快、更有效)的方法使用 SIMD 将 double 转换为 char?
最佳答案
如果你想转换,例如使用 AVX/SSE 每次迭代 16 个 double
到 16 个 char
然后这里是一些有效的代码:
#include <iostream>
#include <immintrin.h>
__m128i proc(const __m256d in0, const __m256d in1, const __m256d in2, const __m256d in3)
{
__m128i v0 = _mm256_cvtpd_epi32(in0);
__m128i v1 = _mm256_cvtpd_epi32(in1);
__m128i v2 = _mm256_cvtpd_epi32(in2);
__m128i v3 = _mm256_cvtpd_epi32(in3);
__m128i v01 = _mm_packs_epi32(v0, v1);
__m128i v23 = _mm_packs_epi32(v2, v3);
return _mm_packs_epi16(v01, v23);
}
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};
for (int i = 0; i < 32; i += 16) // two iterations
{
__m256d in0 = _mm256_loadu_pd(&input[i]); // load 4 x 4 doubles
__m256d in1 = _mm256_loadu_pd(&input[i + 4]);
__m256d in2 = _mm256_loadu_pd(&input[i + 8]);
__m256d in3 = _mm256_loadu_pd(&input[i + 12]);
__m128i out = proc(in0, in1, in2, in3); // pack to 16 chars
_mm_storeu_si128(reinterpret_cast<__m128i*>(&output[i]), out);
}
for (int i = 0; i < 32; ++i)
{
std::cout << (int)output[i] << " ";
}
std::cout << std::endl;
return 0;
}
编译运行:
$ g++ -Wall -mavx double_to_char.cpp && ./a.out
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
请注意,上面的代码只需要 AVX(不需要 AVX2)。
关于c++ - SSE - 从 double 到 char 的 AVX 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30853773/
下面的代码有效,我觉得double(double)和double(*)(double)没有区别,square和 &square,我说得对吗? #include double square(doubl
我知道我的作业很草率,这是我在这门课上的第 4 次作业。任何帮助将不胜感激,谢谢。 double getPrincipal(0); double getRate(0); double getYe
我遇到了那个错误,当我使用类时,我在使用函数指针时遇到了这个错误。我的函数'ope'函数我该如何解决 evaluator::function(){ double (*ope) (dou
问题://故事从哪里开始 Graphics 类型中的方法 drawLine(int, int, int, int) 不适用于参数 (double, double, double, double) g.
我有一张 map> m1 形式的 map .我可以将其复制到 map m2 形式的 map 吗?这样键是相同的,并且 m2 中的值是 get(m1->second) 不使用循环?谢谢! 最佳答案 这样
有没有办法获取vector> 的“.first”和“.second”的连续内存? ?我的意思是: void func(int N, double* x, double* y) { for (i
我正在尝试将自定义 lambda 传递给需要函数指针的函数(更准确地说是 zero 中的 Brent library 函数)。 我的想法是,我将使用参数创建一次 lambda,然后用多个值对其求值 x
这是一个很简单的问题,让我很困惑。 我收到一个源文件的以下错误,但另一个没有: 4 src/Source2.cpp:1466: error: no matching function for cal
struct CalculatorBrain { private var accumulator: Double? func changeSign(operand: Double) -
在我正在进行的项目中,我尝试使用 curlpp库来发出一个简单的 html GET 请求。当我将 cpp 文件传递给 g++ 时,出现以下错误: /usr/local/include/curlpp
不使用double就能获得quadruple精度超过16位的数字吗?如果可能的话,这取决于编译器还是其他?因为我知道有人说他使用double精度,并且具有22位精度。 最佳答案 数据类型double
我正在寻找有关特斯拉 GPU 中硬件如何实现 double 的信息。我读到,两个流处理器正在处理单个 double 值,但我没有找到 nvidia 的任何官方论文。 提前致谢。聚苯硫醚为什么大多数 G
这个问题在这里已经有了答案: Passing capturing lambda as function pointer (10 个答案) 关闭 2 年前。 我有这个错误 error: cannot
情况:我有一个元组列表,其中添加了一个元组: List> list = new List>(); list .Add(new Tuple(2.2, 6.6)); 一切似乎都还好。但是......在 D
我有一个 JList,里面有一堆名字,还有一个包含这些名字值的数组 final Double[] filmcost = { 5.00, 5.50, 7.00, 6.00, 5.00 }; 我想做的是,
我试图找出牛顿法来求方程的根。这个错误出来了,我无法处理。 double fn(double n){ return sin(n)+log(n)-1; } double f1n(double n
我有一个 junit 测试断言两个 Double 对象,具有以下内容: Assert.assertEquals(Double expected, Double result); 这很好,然后我决定将其
我正在尝试引入部分数据文件来填充数组,用户尝试了三次输入正确的数据文件名。我一再遇到这些错误。我知道像 arr 这样的数组只是一个指向内存块的指针。 #include #include #incl
我正在尝试完成复习题(为即将到来的编程决赛),但是,我无法解决这个问题,因为我不断收到错误(标题)。正如预期的那样,我将发布问题和我尝试的解决方案。 问题: 给定以下函数定义:void swap(do
任何人都知道如何实现这一目标。我已经尝试了通常的公式,但我只得到正数 Double.NEGATIVE_INFINITY) return d; } } 这将以相同的概率
我是一名优秀的程序员,十分优秀!