通过编码是否有任何(非微优化)性能增益
float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)
在比较中
float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)
几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.
这句话适用于现代PC架构吗?
UPDATE1
关于评论,请同时考虑这个案例:
float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)
更新2 从评论中引用:
[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多
我认为F#意味着比C#更快,我做了一个可能不好的基准测试工具,C#得到16239ms,而F#做得更差,为49583ms.有人可以解释为什么会这样吗?我正在考虑离开F#并回到C#.是否可以通过更快的代码在F#中获得相同的结果?
这是我使用的代码,我尽可能地使它成为平等.
F#(49583ms)
open System
open System.Diagnostics
let stopwatch = new Stopwatch()
stopwatch.Start()
let mutable isPrime = true
for i in 2 .. 100000 do
for j in 2 .. i do
if i <> j && i % j = 0 then
isPrime <- false
if isPrime then
printfn "%i" i
isPrime <- true
stopwatch.Stop()
printfn "Elapsed time: %ims" stopwatch.ElapsedMilliseconds
Console.ReadKey() |> ignore
Run Code Online (Sandbox Code Playgroud)
C#(16239ms)
using System;
using System.Diagnostics;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{ …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一些合理快速的组件向量加法代码.我正在使用(签名,我相信)64位整数.
功能是
void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) {
for(int i = 0; i < dim; i++) {
a[i] = (a[i]+b[i])%q; // LINE1
}
}
Run Code Online (Sandbox Code Playgroud)
我在icc -std=gnu99 -O3IvyBridge(SSE4.2和AVX,但不是AVX2)上编译(icc以便我以后可以使用SVML).
我的基线是%q从LINE1中删除.100(迭代)函数调用dim=11221184需要1.6秒.ICC自动矢量化SSE代码; 大.
我真的想做模块化的补充.使用%q,ICC不会自动向量化代码,它在11.8秒(!)内运行.即使忽略了之前尝试的自动矢量化,这似乎仍然过分.
由于我没有AVX2,SSE的矢量化需要SVML,这也许就是为什么ICC没有自动矢量化的原因.无论如何,这是我尝试对内循环进行矢量化:
__m128i qs = _mm_set1_epi64x(q);
for(int i = 0; i < dim; i+=2) {
__m128i xs = _mm_load_si128((const __m128i*)(a+i));
__m128i ys = _mm_load_si128((const __m128i*)(b+i));
__m128i zs = _mm_add_epi64(xs,ys);
zs = _mm_rem_epi64(zs,qs);
_mm_store_si128((__m128i*)(a+i),zs);
}
Run Code Online (Sandbox Code Playgroud)
主循环的汇编是: …
我处理图像处理.我需要将16位整数SSE向量除以255.
我不能使用像_mm_srli_epi16()这样的移位运算符,因为255不是2的幂的倍数.
我当然知道可以将整数转换为浮点数,执行除法然后返回转换为整数.
但也许有人知道另一种解决方案......
EDIT2:正如@ShadowRanger指出的那样,这是一种Numpy现象,而不是Python。但是,当在Python中使用列表推导进行计算(因此x+y变为[a+b for a,b in zip(x,y)])时,所有算术运算仍会花费同样长的时间(尽管是Numpy的100倍以上)。但是,当我在真实的仿真中使用整数除法时,它们的运行速度会更快。因此,主要问题仍然存在:即使在Python中,为什么这些测试表明整数除法没有比常规除法更快?
EDIT1:版本:Python 3.5.5,Numpy 1.15.0。
似乎在Python Numpy中,整数除法比(整数的)正规除法更昂贵,这是违反直觉的。测试时,我得到以下信息:
setup_string = 'import numpy as np;\
N=int(1e5);\
x=np.arange(1,N+1, dtype=int);\
y=np.arange(N, dtype=int);'
Run Code Online (Sandbox Code Playgroud)
加法(+)〜0.1s
timeit("x+y", setup=setup_string, number=int(1e3))
0.09872294100932777
Run Code Online (Sandbox Code Playgroud)
减法(-)〜0.1s
timeit("x-y", setup=setup_string, number=int(1e3))
0.09425603999989107
Run Code Online (Sandbox Code Playgroud)
乘法(*)〜0.1s
timeit("x*y", setup=setup_string, number=int(1e3))
0.09888673899695277
Run Code Online (Sandbox Code Playgroud)
除(/)〜0.35s
timeit("x/y", setup=setup_string, number=int(1e3))
0.3574664070038125
Run Code Online (Sandbox Code Playgroud)
整数除(//)〜1s(!)
timeit("x//y", setup=setup_string, number=int(1e3))
1.006298642983893
Run Code Online (Sandbox Code Playgroud)
任何想法为什么会这样?为什么整数除法不快?
python performance numpy integer-division integer-arithmetic
我想将AVX2向量除以常数.我访问了这个问题和许多其他页面.看到可能有助于定点运算的东西,我不明白.所以问题在于这种划分是瓶颈.我试过两种方法:
首先,使用AVX指令进行浮动并执行操作:
//outside the bottleneck:
__m256i veci16; // containing some integer numbers (16x16-bit numbers)
__m256 div_v = _mm256_set1_ps(div);
//inside the bottlneck
//some calculations which make veci16
vecps = _mm256_castsi256_ps (veci16);
vecps = _mm256_div_ps (vecps, div_v);
veci16 = _mm256_castps_si256 (vecps);
_mm256_storeu_si256((__m256i *)&output[i][j], veci16);
Run Code Online (Sandbox Code Playgroud)
使用第一种方法,问题是:没有分割经过的时间是5ns,并且经过的时间是大约60ns.
其次,我存储到一个数组并加载它像这样:
int t[16] ;
inline __m256i _mm256_div_epi16 (__m256i a , int b){
_mm256_store_si256((__m256i *)&t[0] , a);
t[0]/=b; t[1]/=b; t[2]/=b; t[3]/=b; t[4]/=b; t[5]/=b; t[6]/=b; t[7]/=b;
t[8]/=b; t[9]/=b; t[10]/=b; t[11]/=b; t[12]/=b; t[13]/=b; t[14]/=b; t[15]/=b;
return …Run Code Online (Sandbox Code Playgroud) c++ ×2
simd ×2
sse ×2
assembly ×1
avx ×1
avx2 ×1
benchmarking ×1
c ×1
c# ×1
f# ×1
intrinsics ×1
numpy ×1
optimization ×1
performance ×1
primes ×1
python ×1
sse2 ×1
x86 ×1
x86-64 ×1