问题标签 [simd]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - SSE2:双精度对数功能
我需要日志功能的开源(无许可证限制)实现,带有签名的东西
它在英特尔短向量数学库(ICC 的一部分)中可用,但 ICC 既不是免费的也不是开源的。我正在寻找仅使用内在函数的实现。
它应该使用特殊的有理函数逼近。我需要一些几乎与 cmath 日志一样准确的东西,比如 9-10 位十进制数字,但速度更快。
c - 如何使以下代码更快
上面提到的代码在我的程序中被多次调用(profiler 显示 98%)。
编辑:在内部循环中, res1[i + k] 值会为相同的 (i + k) 值加载多次。我在 while 循环中尝试了这个,我将所有 res1 值加载到 simd 寄存器(数组)中,并在最里面的 for 循环中使用数组元素来更新数组元素。完成两个 for 循环后,我将数组值存储回 res1、re2。但是计算时间随之增加。知道我哪里错了吗?这个想法似乎是正确的
欢迎任何使它更快的建议。
c++ - 由于 SSE 中的内存对齐导致的分段错误
我正在研究面部检测,其中我将输入作为 .bmp 文件并检测面部并在面部上绘制一个矩形。
但是当我添加一个名为“cvDetect”的函数来检测人脸时,我遇到了一些分割错误,在下面的代码行中 -
在调试时我发现由于这些函数存在一些内存对齐问题。任何人都可以帮助解决这个问题,代码是 C++,我使用的是 Linux。
c - 使用 SSE 对数组进行索引
假设我有一个数组:
和一个元素
包含 16 个字节,
我想有效地填充一个新__m128i
元素
的值arr
取决于 中的值x
,例如:
实现这一点的命令本质上是从一组不连续的内存位置加载寄存器。我对曾经看过这样一个命令的文档有一种痛苦的模糊记忆,但现在找不到了。它存在吗?在此先感谢您的帮助。
c++ - 访问 mm1 寄存器部件
是否可以访问 mmx 寄存器中的单个字节,例如数组?我有这个代码:
我想将 mm1[1],mm1[2],mm1[3].... 放入 c++ 变量中,例如:
谢谢。
gcc - gcc 中的 SSE(SIMD 扩展)支持
我看到如下代码:
此代码构建良好,并且使用 gcc 可以正常工作(它是内置的 SSE / MMX 扩展和向量数据类型。此代码使用 4 个单浮点数进行 SIMD 向量加法。
我想详细了解此 typedef 行上的每个关键字/函数调用的含义和作用:
vector_size() 函数返回什么;
__attribute__
关键字是什么
这是将浮点数据类型定义为 vfsf 类型的类型吗?
我理解剩下的部分。
谢谢,
-广告
optimization - 近似 log10[x^k0 + k1]
问候。我正在尝试近似函数
Log10[x^k0 + k1],其中 0.21 < k0 < 21, 0 < k1 < ~2000,x 是整数 < 2^14。
k0 & k1 是常数。出于实际目的,您可以假设 k0 = 2.12,k1 = 2660。所需的精度为 5*10^-4 相对误差。
这个函数实际上与 Log[x] 相同,除了在 0 附近,它有很大不同。
我已经提出了一个 SIMD 实现,它比简单的查找表快约 1.15 倍,但如果可能的话,我想改进它,我认为由于缺乏有效的指令,这非常困难。
我的 SIMD 实现使用 16 位定点算法来评估 3 次多项式(我使用最小二乘拟合)。多项式对不同的输入范围使用不同的系数。有 8 个范围,范围 i 跨越 (64)2^i 到 (64)2^(i + 1)。这背后的原因是 Log[x] 的导数随 x 迅速下降,这意味着多项式将更准确地拟合它,因为多项式完全适合导数为 0 的函数超过一定阶数。
使用单个 _mm_shuffle_epi8() 可以非常有效地完成 SIMD 表查找。我使用 SSE 的 float 到 int 转换来获得用于定点逼近的指数和有效数字。我还对循环进行了软件流水线处理,以获得约 1.25 倍的加速,因此可能不太可能进一步优化代码。
我要问的是在更高级别是否有更有效的近似?例如:
- 这个函数是否可以分解为具有有限域的函数,如 log2((2^x) * significand) = x + log2(significand)
因此无需处理不同的范围(表查找)。我认为的主要问题是添加 k1 术语会杀死所有我们知道和喜爱的漂亮日志属性,使其成为不可能。或者是吗?
迭代法?不要这么认为,因为 log[x] 的牛顿法已经是一个复杂的表达式
利用相邻像素的局部性?- 如果 8 个输入的范围在相同的近似范围内,那么我可以查找单个系数,而不是为每个元素查找单独的系数。因此,我可以将其用作快速的常见情况,并在不是时使用较慢的通用代码路径。但就我的数据而言,在此属性保持 70% 的时间之前,范围需要为 ~2000,这似乎并没有使这种方法具有竞争力。
请给我一些意见,尤其是如果您是应用数学家,即使您说做不到。谢谢。
c - 在医学图像重建实现中改善局部性并减少缓存污染
我正在为我的大学进行一项与医疗用途图像重建算法相关的研究。
我被困在长达 3 周的时间里,我需要提高以下代码的性能:
对于任何想知道的人,该代码实现了 MLEM 转发功能,所有变量都是 FLOAT。
经过几次测试,我注意到这部分代码出现了很大的延迟。(你知道,90 - 10 规则)。
后来,我使用 Papi (http://cl.cs.utk.edu/papi/) 来测量 L1D 缓存未命中。正如我所想,Papi 确认性能下降是由于更多的未命中,特别是对于随机访问 b 向量(巨大的大小)。
阅读互联网上的信息到目前为止,我只知道两种提高性能的选择:提高数据局部性或减少数据污染。
为了进行第一个改进,我将尝试将代码更改为可感知缓存,就像 Ulrich Drepper 在每个程序员都应该了解的内存(www.akkadia.org/drepper/cpumemory.pdf)中提出的那样。 1 矩阵乘法。
我相信阻止 SpMV(稀疏矩阵向量乘法)会提高性能。
另一方面,每次程序尝试访问 b 向量时,我们都会遇到所谓的缓存污染。
有没有办法在不使用缓存的情况下使用 SIMD 指令从 b 向量中加载一个值?
此外,可以使用 void _mm_stream_ps(float * p , __m128 a) 之类的函数在向量 b 上存储一个浮点值而不污染缓存?
我不能使用 _mm_stream_ps 因为总是存储 4 个浮点数,但对 b 向量的访问显然是随机的。
我希望清楚我的困境。
更多信息:v 是具有 CRS 格式的稀疏矩阵存储的列值。我意识到如果我尝试将 CRS 格式更改为其他格式,则可以进行其他优化,但是,就像我之前所说的,我已经做了几个月的测试,我知道性能下降与向量 b 上的随机访问有关。从 400.000.000 L1D Misses 当我不存储在向量 b 中时,我可以转到 100~ Misses。
谢谢。
x86 - C++ 中 SSE/AVX 的 x86 CPU 调度
我有一个算法,它受益于 SSE(2) 内在函数的手动优化。此外,该算法未来还将能够受益于 256 位 AVX 寄存器。
我的问题是什么是最好的方法
- 在编译时注册我的类的可用性变体;因此,如果我的类是:
Foo
,FooSSE2
并且FooAVX
我需要一种方法来确定在运行时编译了哪些类。 - 确定当前 CPU 的能力。在最低级别,这将导致
cpuid
调用。 - 在运行时根据编译的内容和支持的内容决定使用什么。
虽然我可以破解上述大部分内容,但它似乎是一个足够常见的问题,必须出现一些最佳实践。理想情况下,我试图避免#ifdef
混乱
optimization - 将 TBB 与 SSE2 内在函数混合
在 parallel_for 中使用 SSE2 内在是一个好主意吗?
由于 SSE2 寄存器的数量有限,是否会在性能方面造成损失?
每个 CPU 芯片都有自己的 SSE2 寄存器吗?