这段代码是否有任何缺点,这似乎是一个更快(和更正)的版本java.lang.Math.round?
public static long round(double d) {
if (d > 0) {
return (long) (d + 0.5d);
} else {
return (long) (d - 0.5d);
}
}
Run Code Online (Sandbox Code Playgroud)
它利用了这样一个事实,即在Java中,截断到长轮到零.
假设我有类似的课程
class Empty{
Empty(int a){ cout << a; }
}
Run Code Online (Sandbox Code Playgroud)
然后我用它来调用它
int main(){
Empty(2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是否会导致在堆栈上分配任何内存以创建"空"对象?显然,参数需要被推入堆栈,但我不想产生任何额外的开销.基本上我使用构造函数作为静态成员.
我想这样做的原因是因为模板.实际的代码看起来像
template <int which>
class FuncName{
template <class T>
FuncName(const T &value){
if(which == 1){
// specific behavior
}else if(which == 2){
// other specific behavior
}
}
};
Run Code Online (Sandbox Code Playgroud)
这让我可以写出像
int main(){
int a = 1;
FuncName<1>(a);
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以专门化一个模板参数,而不必指定类型T.此外,我希望编译器将优化构造函数内的其他分支.如果有人知道这是真的还是如何检查,那将非常感激.我还假设投掷模板进入情况不会改变上面的"空类"问题,是吗?
我试图建立一个简单的前馈神经网络的Java端口.
这显然涉及大量的数值计算,所以我试图尽可能地优化我的中心循环.结果应该在float数据类型的限制范围内正确.
我当前的代码如下所示(错误处理和初始化已删除):
/**
* Simple implementation of a feedforward neural network. The network supports
* including a bias neuron with a constant output of 1.0 and weighted synapses
* to hidden and output layers.
*
* @author Martin Wiboe
*/
public class FeedForwardNetwork {
private final int outputNeurons; // No of neurons in output layer
private final int inputNeurons; // No of neurons in input layer
private int largestLayerNeurons; // No of neurons in largest layer
private …Run Code Online (Sandbox Code Playgroud) java optimization performance micro-optimization neural-network
我正在编写一个程序,需要在紧密的循环中进行大量的二进制搜索 - 至少10 15次.这些以及少量的按位操作将占程序运行时的75%以上,因此使它们快速非常重要.(现在实现它占用了95%以上的时间,但是使用了一个非常不同的实现[不是搜索],我正在替换它.)
要搜索的数组(当然,它不需要实现为数组)非常小.在我目前的情况下,它由41个64位整数组成,但用于优化其他大小的数组的技术将是有用的.(我之前遇到过类似的问题.)
我可以提前分析数据,以确定最有可能的范围以及匹配的频率.收集这些信息并不容易,但我应该在一天结束时收到这些信息.
我的代码可能在C中使用内联汇编; 它将使用最新版本的gcc进行编译.欢迎任何语言的回复; 如果您愿意(例如)FORTRAN,我可以翻译.
那么:我如何有效地实现这种搜索?
澄清:我实际上是使用搜索来测试成员资格,而不是使用数组中的位置.丢弃该信息的解决方案是可以接受的.
最终代码:
long ispow3_tiny(ulong n)
{
static ulong pow3table[] = {
#ifdef LONG_IS_64BIT
12157665459056928801, 0, 4052555153018976267, 1350851717672992089, 0, 450283905890997363, 150094635296999121, 0, 50031545098999707, 0, 16677181699666569, 5559060566555523, 0, 1853020188851841, 617673396283947, 0, 205891132094649, 0, 68630377364883, 22876792454961, 0, 7625597484987, 2541865828329, 0, 847288609443, 282429536481, 0, 94143178827, 0, 31381059609, 10460353203, 0,
#endif
3486784401, 1162261467, 0, 387420489, 0, 129140163, 43046721, 0, 14348907, 4782969, 0, 1594323, 531441, 0, 177147, 0, 59049, 19683, 0, 6561, 2187, 0, …Run Code Online (Sandbox Code Playgroud) gcc提供了可能/不太可能的提示,帮助编译器生成具有更好分支预测的机器代码.
有没有关于如何正确使用或不使用这些提示影响某些真实系统上实际代码性能的数据?
在Java中,让HashMap完全填充这种形式的数据:
HashMap<Integer, int[]> map = new HashMap<Integer, int[]>(1000000, 1);
Run Code Online (Sandbox Code Playgroud)
检查随机密钥是否存在时更快,比如说100:
if (map.get(100) == null))
Run Code Online (Sandbox Code Playgroud)
要么
if (!map.containsKey(100))
Run Code Online (Sandbox Code Playgroud)
?
从微观优化的角度来看问题很有意思.
如果负载与两个早期存储重叠(并且负载未完全包含在最早的存储中),现代Intel或AMD x86实现是否可以从两个存储转发以满足负载?
例如,请考虑以下顺序:
mov [rdx + 0], eax
mov [rdx + 2], eax
mov ax, [rdx + 1]
Run Code Online (Sandbox Code Playgroud)
最后的2字节加载从前一个存储区获取其第二个字节,但是它之前的存储区的第一个字节.这个负载可以存储转发,还是需要等到两个先前的存储都提交给L1?
请注意,通过存储转发,我包括任何可以满足仍然存储在缓冲区中的存储的读取的机制,而不是等待它们提交到L1,即使它是一个比最好的情况"转发"更慢的路径.单店"案例.
我的同事和我自己都没有成功解释为什么GCC,ICC和Clang没有优化这个功能
void f(std::uint64_t a, void * p) {
std::uint8_t *x = reinterpret_cast<std::uint8_t *>(p);
x[7] = a >> 56;
x[6] = a >> 48;
x[5] = a >> 40;
x[4] = a >> 32;
x[3] = a >> 24;
x[2] = a >> 16;
x[1] = a >> 8;
x[0] = a;
}
Run Code Online (Sandbox Code Playgroud)
进入这个
mov QWORD PTR [rsi], rdi
Run Code Online (Sandbox Code Playgroud)
如果我们f用memcpy它来表达,就会发出它mov.如果我们做一些看似微不足道的字节写入序列,为什么不会发生?
我正在处理3D网格中的大量数据,所以我想实现一个简单的迭代器而不是三个嵌套循环.但是,我遇到了性能问题:首先,我只使用int x,y和z变量实现了一个简单的循环.然后我实现了Vector3I结构并使用了 - 并且计算时间加倍.现在我正在努力解决这个问题 - 为什么会这样?我做错了什么?
复制示例:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Runtime.CompilerServices;
public struct Vector2I
{
public int X;
public int Y;
public int Z;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector2I(int x, int y, int z)
{
this.X = x;
this.Y = y;
this.Z = z;
}
}
public class IterationTests
{
private readonly int _countX;
private readonly int _countY;
private readonly int _countZ;
private Vector2I _Vector = new Vector2I(0, 0, 0);
public IterationTests()
{
_countX = 64;
_countY = 64;
_countZ …Run Code Online (Sandbox Code Playgroud) 众所周知,乘法,整数除法和2的幂的模可以作为按位运算更有效地重写:
>>> x = randint(50000, 100000)
>>> x << 2 == x * 4
True
>>> x >> 2 == x // 4
True
>>> x & 3 == x % 4
True
Run Code Online (Sandbox Code Playgroud)
在诸如C/C++和Java等编译语言中,测试表明按位运算通常比算术运算更快.(见这里和这里).但是,当我在Python中测试这些时,我得到了相反的结果:
In [1]: from random import randint
...: nums = [randint(0, 1000000) for _ in range(100000)]
In [2]: %timeit [i * 8 for i in nums]
7.73 ms ± 397 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) …Run Code Online (Sandbox Code Playgroud)