我编写了程序,并在Intel Core i5-2500上的Visual Studio 2010中为x64和x86平台编译.x64版本执行大约需要19秒,x86大约需要17秒.这种行为的原因是什么?
#include "timer.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
/********************DECLARATIONS************************************************/
class Vector
{
public:
Vector():x(0),y(0),z(0){}
Vector(double x, double y, double z)
: x(x)
, y(y)
, z(z)
{
}
double x;
double y;
double z;
};
double Dot(const Vector& a, const Vector& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
class Vector2
{
public:
typedef double value_type;
Vector2():x(0),y(0){}
Vector2(double x, double y)
: x(x)
, …Run Code Online (Sandbox Code Playgroud) 对于C(short,int,long等)中的"标准"有符号整数类型的所有操作,如果它们产生超出[TYPE_MIN,TYPE_MAX]间隔的结果(其中TYPE_MIN,TYPE_MAX是最小值和最大整数值),则表现出未定义的行为可以通过特定整数类型存储的.
但是,根据C99标准,所有intN_t类型都需要具有二进制补码表示:
7.8.11.1精确宽度整数类型
1. typedef名称intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.因此,int8_t表示具有正好8位宽度的有符号整数类型.
这是否意味着intN_tC99 中的类型在整数溢出的情况下表现出良好定义的行为?例如,这段代码定义明确吗?
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在开发一个非常低级别的应用程序,其中性能至关重要.
在调查生成的程序集时,我注意到以下指令:
lea eax,[edx*8+8]
Run Code Online (Sandbox Code Playgroud)
我习惯在使用内存引用时看到添加内容(例如[edx + 4]),但这是我第一次看到乘法.
提前致谢.
多年来我多次读过你应该做XOR ax,ax因为它更快......或者用C编程时使用counter ++或counter + = 1因为它们会INC或ADD ......或者在Netburst Pentium中4 INC比ADD 1慢,因此必须警告编译器你的目标是一个Netburst所以它会将所有var ++翻译成ADD 1 ......
我的问题是:为什么INC和ADD有不同的表现?为什么例如INC声称在Netburst上速度较慢而在其他处理器中比ADD快?
我遇到的一个问题是我的jar文件和我的源文件不匹配.
我想:
我主要使用eclipse; 因此,对Eclipse的解决方案非常感激,但任何IDE(或命令行调试器)都可以.谢谢!
我正在比较Java中嵌套for,while和do-while循环的效率,并且我遇到了一些我需要帮助理解的奇怪结果.
public class Loops {
public static void main(String[] args) {
int L = 100000; // number of iterations per loop
// for loop
double start = System.currentTimeMillis();
long s1 = 0;
for (int i=0; i < L; i++) {
for (int j = 0; j < L; j++) {
s1 += 1;
}
}
double end = System.currentTimeMillis();
String result1 = String.format("for loop: %.5f", (end-start) / 1000);
System.out.println(s1);
System.out.println(result1);
// do-while loop
double start1 = System.currentTimeMillis();
int i = …Run Code Online (Sandbox Code Playgroud) 我正在深入研究指针,因为我不认为我对指针有很好的了解,并在维基百科上看到以下几行:
处理数组时,关键查找操作通常涉及一个称为地址计算的阶段,该阶段涉及构造指向数组中所需数据元素的指针.如果数组中的数据元素具有可被2的幂整除的长度,则此算法通常更有效.
为什么会这样?
"#pragma section <XYZ>"在C中有什么用?
我遇到过使用以下类型的C代码文件: -
#define XYZ "ITEM 26.G03"
#pragma section <XYZ>
Run Code Online (Sandbox Code Playgroud)
XYZ的位置是: #define XYZ "ITEM 26.G03"
我需要一些关于使用的解释 "#pragma section"
我正在看一些通过反汇编一些C程序生成的程序集,我对我经常重复看到的单个优化感到困惑.
当我没有对GCC编译器进行优化时使用subl减法指令,但是当我确实打开了优化(-O3准确地说)时,编译器使用leal指令而不是减法,例如:
没有优化:
83 e8 01 subl $0x1, %eax
Run Code Online (Sandbox Code Playgroud)
优化
8d 6f ff leal -0x1(%edi), %ebp
Run Code Online (Sandbox Code Playgroud)
这两条指令都是3个字节长,所以我没有在这里看到优化.有人可以帮助我并尝试解释编译器的选择吗?
任何帮助,将不胜感激.
我想学习如何编写更好的代码,利用CPU的缓存.使用连续记忆似乎是理想的情况.话虽如此,我很好奇是否可以使用非连续内存进行类似的改进,但是需要遵循一系列指针,例如:
struct Position {
int32_t x,y,z;
}
...
std::vector<Position*> posPointers;
...
updatePosition () {
for (uint32_t i = 0; i < posPointers.size(); i++) {
Position& nextPos = *posPointers[i];
nextPos.x++;
nextPos.y++;
nextPos.z++;
}
}
Run Code Online (Sandbox Code Playgroud)
这只是一些粗略的模拟代码,为了正确地学习这个,我们只是说所有的位置结构都是在整个堆中随机创建的.
英特尔的i7等现代智能处理器能不能直接看到它很快就会需要X_ptr数据?以下代码行会有帮助吗?
... // for loop
Position& nextPos1 = *posPointers[i];
Position& nextPos2 = *posPointers[i+1];
Position& nextPos3 = *posPointers[i+2];
Position& nextPos4 = *posPointers[i+3];
... // Work on data here
Run Code Online (Sandbox Code Playgroud)
我读过一些演示幻灯片,似乎表明这样的代码会导致处理器预取一些数据.真的吗?我知道有非标准的,特定于平台的方式来调用预取__builtin_prefetch,但是把它扔到这个地方看起来就像是一个丑陋的过早优化.我正在寻找一种方法,我可以下意识地编写缓存效率的代码.