这是一段看似非常特殊的C++代码.出于某种奇怪的原因,奇迹般地对数据进行排序使得代码几乎快了六倍.
#include <algorithm>
#include <ctime>
#include <iostream>
int main()
{
// Generate data
const unsigned arraySize = 32768;
int data[arraySize];
for (unsigned c = 0; c < arraySize; ++c)
data[c] = std::rand() % 256;
// !!! With this, the next loop runs faster.
std::sort(data, data + arraySize);
// Test
clock_t start = clock();
long long sum = 0;
for (unsigned i = 0; i < 100000; ++i)
{
// Primary loop
for (unsigned c = 0; c < arraySize; ++c) …Run Code Online (Sandbox Code Playgroud) 我为Project Euler Q14编写了这两个解决方案,在汇编和C++中.它们是用于测试Collatz猜想的相同蛮力方法.装配解决方案与组装
nasm -felf64 p14.asm && gcc p14.o -o p14
Run Code Online (Sandbox Code Playgroud)
C++是用.编译的
g++ p14.cpp -o p14
Run Code Online (Sandbox Code Playgroud)
部件, p14.asm
section .data
fmt db "%d", 10, 0
global main
extern printf
section .text
main:
mov rcx, 1000000
xor rdi, rdi ; max i
xor rsi, rsi ; i
l1:
dec rcx
xor r10, r10 ; count
mov rax, rcx
l2:
test rax, 1
jpe even
mov rbx, 3
mul rbx
inc rax
jmp c1
even:
mov rbx, 2 …Run Code Online (Sandbox Code Playgroud) 我一直在绞尽脑汁想要完成这项任务一周,我希望有人能带领我走向正确的道路.让我从教师的指示开始:
您的作业与我们的第一个实验作业相反,即优化素数计划.你在这个任务中的目的是使程序失望,即让它运行得更慢.这两个都是CPU密集型程序.他们需要几秒钟才能在我们的实验室电脑上运行.您可能无法更改算法.
要取消优化程序,请使用您对英特尔i7管道如何运行的了解.想象一下重新排序指令路径以引入WAR,RAW和其他危险的方法.想一想最小化缓存有效性的方法.恶魔无能.
该作业选择了Whetstone或Monte-Carlo程序.缓存有效性评论大多只适用于Whetstone,但我选择了Monte-Carlo模拟程序:
// Un-modified baseline for pessimization, as given in the assignment
#include <algorithm> // Needed for the "max" function
#include <cmath>
#include <iostream>
// A simple implementation of the Box-Muller algorithm, used to generate
// gaussian random numbers - necessary for the Monte Carlo method below
// Note that C++11 actually provides std::normal_distribution<> in
// the <random> library, which can be used instead of this function
double gaussian_box_muller() {
double x = 0.0;
double y = 0.0; …Run Code Online (Sandbox Code Playgroud) 如果我有一个整数n,并且我想知道最高位的位置(也就是说,如果最低有效位在右边,我想知道最左边位的位置是1),找出最快捷/最有效的方法是什么?
我知道POSIX支持ffs()strings.h中的一个方法来查找第一个设置位,但似乎没有相应的fls()方法.
是否有一些非常明显的方法可以解决这个问题?
如果你不能使用POSIX功能来实现可移植性呢?
编辑:如何在32位和64位架构上运行的解决方案(许多代码清单似乎只能在32位整数上运行).
xor eax, eax将永远设置eax为零,对吗?那么,为什么MSVC++有时会把它放在我的可执行代码中呢?这样效率更高mov eax, 0吗?
012B1002 in al,dx
012B1003 push ecx
int i = 5;
012B1004 mov dword ptr [i],5
return 0;
012B100B xor eax,eax
Run Code Online (Sandbox Code Playgroud)
另外,这意味着什么in al, dx?
我正在寻找一种有效的方法来确定在整数中设置的最低有效位的位置,例如对于0x0FF0,它将是4.
这是一个简单的实现:
unsigned GetLowestBitPos(unsigned value)
{
assert(value != 0); // handled separately
unsigned pos = 0;
while (!(value & 1))
{
value >>= 1;
++pos;
}
return pos;
}
Run Code Online (Sandbox Code Playgroud)
任何想法如何挤出一些周期?
(注意:这个问题适合喜欢这类事情的人,而不是人们告诉我xyzoptimization是邪恶的.)
[编辑] 感谢大家的想法!我也学到了其他一些东西.凉!
我需要找到向量中的max元素,所以我正在使用std::max_element,但我发现它是一个非常慢的函数,所以我编写了自己的版本并设法获得x3更好的性能,这里是代码:
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/time.h>
double getRealTime()
{
struct timeval tv;
gettimeofday(&tv, 0);
return (double) tv.tv_sec + 1.0e-6 * (double) tv.tv_usec;
}
inline int my_max_element(const std::vector<int> &vec, int size)
{
auto it = vec.begin();
int max = *it++;
for (; it != vec.end(); it++)
{
if (*it > max)
{
max = *it;
}
}
return max;
}
int main()
{
const int size = 1 << 20;
std::vector<int> vec;
for (int …Run Code Online (Sandbox Code Playgroud) 给定std::bitset<64> bits任意数量的位和位位置X(0-63)
在X位或更低位计数位的最有效方法是什么,如果未设置X位,则返回0
注意:如果设置该位,则返回始终至少为1
蛮力方式很慢:
int countupto(std::bitset<64> bits, int X)
{
if (!bits[X]) return 0;
int total=1;
for (int i=0; i < X; ++i)
{
total+=bits[i];
}
return total;
}
Run Code Online (Sandbox Code Playgroud)
这个count()方法bitset将为您popcount提供所有位,但bitset不支持范围
注意:这不是如何计算32位整数中的设置位数?因为它询问所有位而不是0到X的范围
对于min(ctz(x), ctz(y)),我们可以使用ctz(x | y)来获得更好的性能。但是关于max(ctz(x), ctz(y))?
ctz表示“计数尾随零”。
C++ 版本(编译器资源管理器)
#include <algorithm>
#include <bit>
#include <cstdint>
int32_t test2(uint64_t x, uint64_t y) {
return std::max(std::countr_zero(x), std::countr_zero(y));
}
Run Code Online (Sandbox Code Playgroud)
Rust 版本(编译器资源管理器)
pub fn test2(x: u64, y: u64) -> u32 {
x.trailing_zeros().max(y.trailing_zeros())
}
Run Code Online (Sandbox Code Playgroud)