我一直在英特尔Core Duo上分析我们的一些核心数学,并且在研究平方根的各种方法时,我注意到一些奇怪的事情:使用SSE标量操作,采用倒数平方根并乘以它更快获取sqrt,而不是使用本机sqrt操作码!
我正在测试它的循环类似于:
inline float TestSqrtFunction( float in );
void TestFunc()
{
#define ARRAYSIZE 4096
#define NUMITERS 16386
float flIn[ ARRAYSIZE ]; // filled with random numbers ( 0 .. 2^22 )
float flOut [ ARRAYSIZE ]; // filled with 0 to force fetch into L1 cache
cyclecounter.Start();
for ( int i = 0 ; i < NUMITERS ; ++i )
for ( int j = 0 ; j < ARRAYSIZE ; ++j )
{
flOut[j] = TestSqrtFunction( flIn[j] ); …Run Code Online (Sandbox Code Playgroud) 如果我遇到if (!this) return;应用程序中的旧代码,那么风险有多严重?这是一个危险的滴答作响的定时炸弹需要立即在应用程序范围内搜索并摧毁努力,还是更像是可以安静地留在原点的代码气味?
当然,我不打算编写执行此操作的代码.相反,我最近在我们的应用程序的许多部分使用的旧核心库中发现了一些东西.
想象一下,一个CLookupThingy类具有非虚拟 CThingy *CLookupThingy::Lookup( name )成员函数.显然,那些牛仔时代的程序员遇到了许多崩溃事件,其中NULL CLookupThingy *是从函数传递的,而不是修复数百个调用站点,他悄悄地修复了Lookup():
CThingy *CLookupThingy::Lookup( name )
{
if (!this)
{
return NULL;
}
// else do the lookup code...
}
// now the above can be used like
CLookupThingy *GetLookup()
{
if (notReady()) return NULL;
// else etc...
}
CThingy *pFoo = GetLookup()->Lookup( "foo" ); // will set pFoo to NULL without crashing
Run Code Online (Sandbox Code Playgroud)
我本周早些时候发现了这颗宝石,但现在我是否应该解决这个问题.这是我们所有应用程序使用的核心库.其中一些应用程序已经发送给数百万客户,它似乎工作正常; 该代码没有崩溃或其他错误.删除if !this查找函数将意味着修复数千个可能传递NULL的调用站点; 不可避免地会有一些人被遗漏,引入新的错误,这些错误将在未来一年的发展中随机出现.
所以除非绝对必要,否则我倾向于不管它. …
我正在使用Chrome扩展程序作为内部工具.它的必要行为是:
之前已经问过这个问题,但答案是" 使用NPAPI ",而NPAPI现在已经废弃了.
那么,目前实现这一目标的方法是什么?我看过的是:
我可以尝试另一种方法吗?
我在x86 Linux机器上有一个死堆进程的全堆核心转储(内核2.6.35-22,如果重要的话),我试图在GDB中调试.
是否有我可以使用的GDB命令,这意味着"向我显示此进程分配的所有内存地址区域的列表?" 换句话说,我可以弄清楚我可以在这个转储中检查的所有可能的有效内存地址是什么吗?
我问的原因是我需要在整个进程堆中搜索某个二进制字符串,并且为了使用该find命令,我需要有一个起始和结束地址.简单地从0x00搜索到0xff ..不起作用,因为find一旦遇到它无法访问的地址就会停止:
(gdb)find/w 0x10000000,0xff000000,0x12345678
警告:无法访问0x105ef883处的目标内存,暂停搜索.
因此,我需要获取内存中所有可读地址区域的列表,以便我可以一次搜索一个.
(我之所以要做这是我需要找到所有内存点结构在某个地址.)
没有show mem,show proc,info mem,info proc似乎做什么,我需要.
因为我们的应用程序具有硬性能和内存限制,我们的编码标准禁止使用默认堆 - 即,不malloc,没有默认值new.每个内存分配必须选择一些特定的分配器; 就像是
// declared globally
void* operator new( size_t size, CustomAllocHeap* heap, const char* perpetrator_name )
{
return heap->Allocate( size, perpetrator_name );
}
// imagine a bunch of CustomAllocHeap's declared globally or statically, thus
Vector* v = new( gPhysicsHeap, __FUNCTION__ ) Vector( 1.0f, 2.0f, 3.0f, 4.0f );
// or in a class
Thingy* p = new( this->LocalArenaHeap, __FUNCTION__ ) Thingy();
Run Code Online (Sandbox Code Playgroud)
尽管我们在代码中保持了良好的规范,但是一些标准的C++组件(容器std::function)却隐蔽地调用默认new堆,这非常糟糕.
new以某种方式完全禁用默认值会很好,因此隐式导致默认分配的任何代码行都会立即引发编译器错误.这会让我们马上注意到这些事情.
我们显然可以new抛出运行时错误,即
void* operator new …Run Code Online (Sandbox Code Playgroud) 我正在查看我的程序的解散(因为它崩溃了),并注意到很多
xchg ax, ax
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索它,发现它本质上是一个小鸟,但为什么visual studio会做一个xchg而不是noop?
该应用程序是由Visual Studio编译的C#.NET3.5 64位应用程序
我正在优化一个在我们应用程序的最内层循环中调用的构造函数.有问题的类大约有100个字节宽,由一堆ints,floats,bools和普通的结构组成,应该是可以轻易复制的(它有一个非常重要的默认构造函数,但没有析构函数或虚函数).它的构建经常足以使每个纳秒的时间花费在我们需要购买的大约6,000美元的额外服务器硬件上.
但是,我发现GCC没有为这个构造函数发出非常有效的代码(即使使用了-O3 -marchetc).GCC的构造函数实现,通过初始化列表填充默认值,运行大约需要34ns.如果不是使用这个默认构造函数,而是使用手写函数,该函数使用各种SIMD内在函数和指针数学直接写入对象的内存空间,构造大约需要8ns.
当我__attribute__在SIMD边界上进行内存对齐时,我可以让GCC为这些对象发出有效的构造函数吗?或者我必须采用老派的技巧,比如在汇编中编写我自己的内存初始化程序?
此对象只构造为堆栈上的本地对象,因此任何新的/ malloc开销都不适用.
语境:
通过在堆栈上将其构造为局部变量,选择性地使用非默认值写入一些字段,然后将其(通过引用)传递给函数来使用此类,该函数将其引用传递给另一个,依此类推.
struct Trivial {
float x,y,z;
Trivial () : x(0), y(0), z(0) {};
};
struct Frobozz
{
int na,nb,nc,nd;
bool ba,bb,bc;
char ca,cb,cc;
float fa,fb;
Trivial va, vb; // in the real class there's several different kinds of these
// and so on
Frobozz() : na(0), nb(1), nc(-1), nd(0),
ba(false), bb(true), bc(false),
ca('a'), cb('b'), cc('c'),
fa(-1), fb(1.0) // etc
{}
} …Run Code Online (Sandbox Code Playgroud) 我想要一个C++ 0x static_assert来测试给定的结构类型是否是POD(以防止其他程序员无意中用新成员破坏它).即
struct A // is a POD type
{
int x,y,z;
}
struct B // is not a POD type (has a nondefault ctor)
{
int x,y,z;
B( int _x, int _y, int _z ) : x(_x), y(_y), z(_z) {}
}
void CompileTimeAsserts()
{
static_assert( is_pod_type( A ) , "This assert should not fire." );
static_assert( is_pod_type( B ) , "This assert will fire and scold whoever added a ctor to the POD type." ); …Run Code Online (Sandbox Code Playgroud) 在我们的应用程序的Linux版本中,我需要一个用于嵌入式探查器的高分辨率计时器.我们的分析器测量的范围与单个功能一样小,因此它需要一个优于25纳秒的定时器精度.
以前我们的实现使用内联汇编和rdtsc操作直接从CPU查询高频定时器,但这是有问题的,需要经常重新校准.
所以我尝试使用该clock_gettime函数来查询CLOCK_PROCESS_CPUTIME_ID.文档声称这给了我纳秒时间,但我发现单次调用的开销clock_gettime()超过250ns.这使得不可能将事件计时100ns,并且在计时器功能上具有如此高的开销会严重降低应用程序性能,从而扭曲配置文件超出值.(我们每秒有数十万个分析节点.)
有没有办法调用clock_gettime()开销小于¼μs?或者是否有其他方法可以可靠地获得时间戳计数器,开销<25ns?还是我坚持使用rdtsc?
下面是我过去常用的代码clock_gettime().
// calls gettimeofday() to return wall-clock time in seconds:
extern double Get_FloatTime();
enum { TESTRUNS = 1024*1024*4 };
// time the high-frequency timer against the wall clock
{
double fa = Get_FloatTime();
timespec spec;
clock_getres( CLOCK_PROCESS_CPUTIME_ID, &spec );
printf("CLOCK_PROCESS_CPUTIME_ID resolution: %ld sec %ld nano\n",
spec.tv_sec, spec.tv_nsec );
for ( int i = 0 ; i < TESTRUNS ; ++ i …Run Code Online (Sandbox Code Playgroud) 我想将Python部署到我的组织中的非程序员,这样安装过程完全包括同步Perforce中的目录,并且可能运行一个设置环境变量的批处理文件.
是否有可能以这样的方式打包Miniconda只需复制目录即可"安装"?它的安装程序有什么作用?
这样做的原因是我想通过为他们提供可以从命令行运行的Python脚本来为我们的艺术家自动执行某些任务.但是我需要将解释器放到他们的机器上,而不必运行任何类型的安装程序或卸载程序,或任何可能以非幂等方式失败的进程.设置env变量的批处理文件很好,因为它是幂等的.可以在中途失败并将工作站置于需要干预修复的状态的安装程序不是.
特别是,为每个人的安装添加一个库应该包括我conda在我的桌面上使用,检查随后的目录到P4,然后让艺术家用他们的下一个自动选择它p4 sync.
我看了WinPython,但是1.4GB它太大了.便携式Python已经不存在了.
我们完全是Windows商店,所以不需要Linux或Mac便携式解决方案.
c++ ×4
performance ×3
assembly ×2
gcc ×2
linux ×2
x86 ×2
anaconda ×1
c ×1
c++11 ×1
gdb ×1
javascript ×1
new-operator ×1
profiling ×1
python ×1
sse ×1
type-traits ×1
ubuntu ×1
visual-c++ ×1
x86-64 ×1