我想学习如何编写更好的代码,利用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,但是把它扔到这个地方看起来就像是一个丑陋的过早优化.我正在寻找一种方法,我可以下意识地编写缓存效率的代码.
如果你想看到实际的例外,你需要一台64位的机器.我已经创建了一些可以解决问题的虚拟类.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class InnerType
{
char make;
char model;
UInt16 series;
}
[StructLayout(LayoutKind.Explicit)]
public class OutterType
{
[FieldOffset(0)]
char blah;
[FieldOffset(1)]
char blah2;
[FieldOffset(2)]
UInt16 blah3;
[FieldOffset(4)]
InnerType details;
}
class Program
{
static void Main(string[] args)
{
var t = new OutterType();
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在64 clr上运行它,我收到一个类型加载异常,
System.TypeLoadException was unhandled
Message="Could not load type 'Sample.OutterType' from assembly 'Sample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 4 that is incorrectly aligned or …Run Code Online (Sandbox Code Playgroud) 我有一个32位的exe,当它检测到操作系统是64位时需要动态加载64位dll.这可以通过LoadLibrary吗?如果没有,是否有其他方法可以实现相同的目标?
我的C代码中有一个for循环,如下所示:
for(i=0; i<100000; i++){
a[i] = simulate(); // simulate() function simulates some system
}
Run Code Online (Sandbox Code Playgroud)
我们看到每次迭代的计算都与其他迭代无关(元素的顺序a[]对我来说并不重要).我想使用多线程并行化这个for循环的计算.我不完全清楚如何在C中这样做?我有一台8处理器的机器,所以我可以并行运行8个线程.
在" 游戏编码完成"第3版中,作者提到了一种减少数据结构大小和提高访问性能的技术.从本质上讲,它依赖于当成员变量与内存对齐时获得性能的事实.这是编译器可以利用的明显潜在优化,但通过确保每个变量对齐,它们最终会膨胀数据结构的大小.
或者这至少是他的主张.
他说,真正的性能提升是通过使用你的大脑并确保你的结构设计得合理,以利用速度增加,同时防止编译器膨胀.他提供了以下代码片段:
#pragma pack( push, 1 )
struct SlowStruct
{
char c;
__int64 a;
int b;
char d;
};
struct FastStruct
{
__int64 a;
int b;
char c;
char d;
char unused[ 2 ]; // fill to 8-byte boundary for array use
};
#pragma pack( pop )
Run Code Online (Sandbox Code Playgroud)
struct在未指定的测试中使用上述对象,他报告了性能增加15.6%(222ms与之相比192ms)和更小的尺寸FastStruct.这对我来说都是有意义的,但它在我的测试中无法阻止:

同时结果和大小(计数char unused[ 2 ])!
现在,如果#pragma pack( push, 1 )仅隔离FastStruct(或完全删除),我们确实看到了差异:

所以,最后,问题在于:现代编译器(特别是VS2010)已经针对比特对齐进行了优化,因此性能提升不足(但增加结构尺寸作为副作用,如Mike …
c++ compiler-construction optimization performance visual-studio-2010
这对我来说真的是一个奇怪的错误,我花了很长时间才弄清楚发生了什么.为了简化和重现,只需使用VS2005创建一个空的win32控制台应用程序,并在main方法中使用此代码:
float a = 411.00418f;
float b = 1.0f;
float c = 0.076279849f;
unsigned short result = (unsigned short)( (a-b)/c );
unsigned short result2 = (unsigned short)( (float)((a-b)/c) );
// Debug: 5374, 5375
// Release: 5374, 5374
printf("%d, %d\n", result, result2);
Run Code Online (Sandbox Code Playgroud)
为什么result2在调试/释放模式下显示不同的值?
有类似Java的东西equals()吗?要比较对象是否是同一类型?
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof ViewMode)) {
return false;
}
ViewMode dm = (ViewMode) obj;
return dm.width == w
&& dm.h == h
&& dm.b == b
&& dm.f == f;
}
public int hashCode() {
return w ^ h ^ f ^ b ;
}
Run Code Online (Sandbox Code Playgroud) 没有裂变的代码看起来像这样:
int check(int * res, char * map, int n, int * keys){
int ret = 0;
for(int i = 0; i < n; ++i){
res[ret] = i;
ret += map[hash(keys[i])]
}
return ret;
}
Run Code Online (Sandbox Code Playgroud)
裂变:
int check(int * res, char * map, int n, int * keys){
int ret = 0;
for(int i = 0; i < n; ++i){
tmp[i] = map[hash(keys[i])];
}
for(int i = 0; i < n; ++i){
res[ret] = i;
ret += tmp[i];
}
return …Run Code Online (Sandbox Code Playgroud) 我总是在读取指针算法的定义,只要你不离开数组的边界即可.我不确定我完全理解这意味着什么,我有点担心.因此这个问题.
假设我从一个指向数组开头的指针开始:
int *p = (int*) malloc(4 * sizeof(int));
Run Code Online (Sandbox Code Playgroud)
现在我创建了两个位于数组边界之外的新指针:
int *q = p + 10;
int *r = p - 2;
Run Code Online (Sandbox Code Playgroud)
现在指针q-10,q-9..., ,r+2,r+3等所有的谎言数组的边界内.它们有效吗?例如,r[3] 保证给出相同的结果p[1]?
我做了一些测试,它的工作原理.但我想知道这是否适用于通常的C规范.具体来说,我使用的是Visual Studio 2010,Windows,而且我使用的是原生C(非C++)编程.我被覆盖了吗?
我意识到差异可以忽略不计,但是在尝试将无符号长度归零时哪个更有效?
unsigned long x;
...
x=0;
--OR--
x^=x;
Run Code Online (Sandbox Code Playgroud)
泰勒
c++ ×6
c ×5
performance ×4
64-bit ×2
optimization ×2
pointers ×2
x86 ×2
.net ×1
arrays ×1
c# ×1
caching ×1
comparison ×1
cpu-cache ×1
loadlibrary ×1
memory ×1
variables ×1
visual-c++ ×1
xor ×1