我有以下一段(伪)代码:
static void ConvertBuffer( unsigned char * buffer, const int width )
{
#pragma omp parallel for
for ( int x = 0; x < width; ++x ) // one image row
{
RGB rgb = {0,0,0}; HSB hsb;
rgb.red = (float)buffer[x] / 255.;
RGBToHSB(rgb, hsb);
buffer[x] = hsb.brightness * 255;
}
}
这是RGB→HSB转换算法的非常幼稚的实现。
第一种实现将一次拉一条扫描线(=图像的一行),在我的情况下为65536字节。但是,在经过特定系统的反复试验之后,我发现如果一次可以处理16条扫描线(= 1048576字节),我可以将总计算时间减少2倍。
有什么工具可以让我在运行时猜测该幻数,这样我就无需在代码中的某个地方硬编码16的幻数了?
如果我知道
RGBToHSB
令人尴尬地是并行的并且对缓存友好,那么我是否可以完全填充L3 cache
并且应该接近最大可能的速度?供参考,我的系统描述如下:
$ sudo likwid-topology
-------------------------------------------------------------
CPU type: Intel Core SandyBridge processor
*************************************************************
Hardware Thread Topology
*************************************************************
Sockets: 1
Cores per socket: 4
Threads per core: 1
-------------------------------------------------------------
HWThread Thread Core Socket
0 0 0 0
1 0 1 0
2 0 2 0
3 0 3 0
-------------------------------------------------------------
Socket 0: ( 0 1 2 3 )
-------------------------------------------------------------
*************************************************************
Cache Topology
*************************************************************
Level: 1
Size: 32 kB
Cache groups: ( 0 ) ( 1 ) ( 2 ) ( 3 )
-------------------------------------------------------------
Level: 2
Size: 256 kB
Cache groups: ( 0 ) ( 1 ) ( 2 ) ( 3 )
-------------------------------------------------------------
Level: 3
Size: 6 MB
Cache groups: ( 0 1 2 3 )
-------------------------------------------------------------
*************************************************************
NUMA Topology
*************************************************************
NUMA domains: 1
-------------------------------------------------------------
Domain 0:
Processors: 0 1 2 3
Relative distance to nodes: 10
Memory: 122.332 MB free of total 5898.17 MB
-------------------------------------------------------------
最佳答案
您不能真正定义缓冲的“正确大小”。我的答案是将其设置得尽可能大。我会说介于10MB到100MB之间,但是如果可以承受,可以将其设置为较高,如果RAM不足,则可以将其设置为较低。
如果要读取文件并写入文件(相同或另一个),则应考虑使用内存映射文件。这样,您就可以摆脱缓冲(由操作系统管理),并且可以为整个映像调用一次函数。请注意,如果您的映像大于4GB,则在32位系统上这可能不是一个好主意。