现代 x86_64 CPU 上的 AVX/SSE 求幂需要多少个时钟周期?
我是关于:pow(x, y) = exp(y*log(x))
即exp() 和 log() AVX x86_64 指令都需要特定的已知周期数吗?
_mm256_exp_ps() _mm256_log_ps() 或者循环数可能会根据指数级而变化,是否有最大循环数可以消耗指数?
最佳答案
x86 SIMD 指令集(即不是 x87),至少到 AVX2,不包括 SIMD exp、log 或 pow pow(x,0.5) 除外,它是平方根。
然而,有一些 SIMD 数学库是根据具有这些函数(以及其他函数)的 SIMD 指令构建的。英特尔的 SVML 包括:
__m256 _mm256_exp_ps(__m256)
__m256 _mm256_log_ps(__m256)
__m256 _mm256_pow_ps(__m256, __m256)
英特尔虚伪地称其为内在函数,而实际上它们是通过多条指令运行的。 SVML 是闭源且昂贵的。但是,通过在安装英特尔 OpenCL 运行时后搜索 svml,我在 OpenCL 目录中找到了一些 svml 文件,因此我认为您可以通过英特尔的 OpenCL 运行时间接获取 SVML。
AMD 还提供了一个名为 LibM 的 SIMD 数学库,它是封闭源代码但免费的,它也有自己的 SIMD 数学函数:
__m128 amd_vrs4_expf(__m128)
__m128 amd_vrs4_logf(__m128)
__m128 amd_vrs4_powf(__m128, __m128)
阿格纳雾的 Vector Class Library为 SVML 和 LibM 提供接口(interface)。请参阅文件 vectormath_lib.h。从这里您可以找出来自 SVML 和 LibM 的相应功能。
Agner 还为这些功能提供了他自己的代码,他声称这些代码可以与专有的 Intel 和 AMD 版本竞争。对于函数的 Agner 版本,请查看 vectormath_exp.h 例如查看 exp_f、log_f 和 pow_template_f,然后查看生成的程序集。
可以使用SVML、LibM、Agner自带的函数对exp和log函数进行计时。但是,您应该知道 SVML 和 LibM 在其他硬件上运行不佳。例如,AMD 针对 Intel 没有的 FMA4 进行了优化(但 Intel 最初计划拥有 FMA4,然后在 AMD 已经计划 FMA4 后突然更改为 FMA3)。 Intel appears to do something ummm...well I suggest you read about it .
因此,如果您分别在 AMD 或 Intel 处理器上计时 SVML 或 LibM,您可能会得到非常不同的性能结果 (unless you manage to replace Intel's CPU dispatch function)。与 GPU 不同,x86 指令集是公开可用的,因此您可以构建自己的 exp 和 log 函数,而这正是 Agner 所做的。
更新
Glibc 2.22(应该很快就会出来)有一个 vector 数学库叫做 libmvec .显然它从 -O1 以及 -ffast-math 和 -fopenmp 开始启用。我不确定为什么 fast-math 和 OpenMP 是必需的(特别是在下面的示例中,因为关联数学不是必需的)但是最终在 GNU C 标准库中有一个 SIMD 数学库真是太好了。
//gcc ./cos.c -O1 -fopenmp -ffast-math -lm -mavx2
#include <math.h>
int N = 3200;
double b[3200];
double a[3200];
int main (void)
{
int i;
#pragma omp simd
for (i = 0; i < N; i += 1)
{
b[i] = cos (a[i]);
}
return (0);
}
关于c++ - 在现代 x86_64 CPU 上,AVX/SSE 求幂需要多少个时钟周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502095/
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我正在尝试复制此GETcurl请求:curl-D--XGET-H"Authorization:BasicdGVzdEB0YXByZXNlYXJjaC5jb206NGMzMTg2Mjg4YWUyM2ZkOTY2MWNiNWRmY2NlMTkzMGU="-H"Content-Type:application/json"http://staging.example.com/api/v1/campaigns在Ruby中,通过电子邮件+apikey生成身份验证:auth="Basic"+Base64::encode64("test@example.com:4c3186288ae23fd9661c
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t