prefetch.hierarchy.type.c

来自「代码优化,有效使用内存,透视优化技术,对比优化方法,如果你在追求代码效率的最大化」· C语言 代码 · 共 187 行

C
187
字号
/*----------------------------------------------------------------------------
 *
 *					THE EXAMPLE DEMONSTRATING THE INFLUENCE
 *				OF PREFETCHED CACHE HIERARCHY ON THE PERFORMANCE
 *				=================================================
 *
 * Build 0x002 10.08.2002
----------------------------------------------------------------------------*/
#define BLOCK_SIZE	(4*M)
#define STEP_SIZE	32

//#include <math.h> 
#include <DoCPU.h>
#include <DoCPU.cmd.h>

/*----------------------------------------------------------------------------
 *
 *						TEST WITHOUT PREFETCHING
 *										(non-optimized version)
 *
----------------------------------------------------------------------------*/
int no_prefetch(int *p)
{
	int a;
	int x = 0;

	for(a = 0; a < BLOCK_SIZE; a += STEP_SIZE)
	{
		// performing some calculations (which in particular is not important)
		x += a/(a+1);
	
		// read the next portion of cells
		x += *(int *)((char *)p + a + 0);
		x += *(int *)((char *)p + a + 4);
		x += *(int *)((char *)p + a + 8);
		x += *(int *)((char *)p + a + 12);
		x += *(int *)((char *)p + a + 16);
		x += *(int *)((char *)p + a + 20);
		x += *(int *)((char *)p + a + 24);
		x += *(int *)((char *)p + a + 28);
	}
return x;
}

/*----------------------------------------------------------------------------
 *
 *						TEST WITH prefetchnta
 *								mem -> L1
 *
----------------------------------------------------------------------------*/
int have_prefetchnta(int *p)
{
	int a;
	int x = 0;

	for(a = 0; a < BLOCK_SIZE; a += STEP_SIZE)
	{
		// issue the command for prefetching the next cache line into L1 cache
		// and it will load in parallel with performing calculations of a/(a+1);
		// when appropriate cell will be requested, it will be present in cache
		// and the processor won't have to wait for it to load
		__prefetchnta((char *)((char *)p + a + STEP_SIZE*6));

		// performing some calculations
		x += a/(a+1);

		// reading the next portion of cells
		x += *(int *)((char *)p + a + 0);
		x += *(int *)((char *)p + a + 4);
		x += *(int *)((char *)p + a + 8);
		x += *(int *)((char *)p + a + 12);
		x += *(int *)((char *)p + a + 16);
		x += *(int *)((char *)p + a + 20);
		x += *(int *)((char *)p + a + 24);
		x += *(int *)((char *)p + a + 28);
	}
return x;
}


/*----------------------------------------------------------------------------
 *
 *						TEST WITH prefetchnt0
 *								mem -> L2 -> L1
 *
----------------------------------------------------------------------------*/
int have_prefetcht0(int *p)
{
	int a;
	int x = 0;

	for(a = 0; a < BLOCK_SIZE; a += STEP_SIZE)
	{
		// issue the command for prefetching the next cache line into L1/L2 cache
		// and it will load in parallel with performing calculations of a/(a+1);
		// when appropriate cell will be requested, it will be present in cache
		// and the processor won't have to wait for it to load
		_prefetcht0((char *)((char *) p + a + STEP_SIZE*6));

		// performing some calculations
		x += a/(a+1);

		// reading the next portion of cells
		x += *(int *)((char *)p + a + 0);
		x += *(int *)((char *)p + a + 4);
		x += *(int *)((char *)p + a + 8);
		x += *(int *)((char *)p + a + 12);
		x += *(int *)((char *)p + a + 16);
		x += *(int *)((char *)p + a + 20);
		x += *(int *)((char *)p + a + 24);
		x += *(int *)((char *)p + a + 28);
	}
return x;
}

/*----------------------------------------------------------------------------
 *
 *						TEST WITH prefetchnt1
 *								mem -> L2
 *
----------------------------------------------------------------------------*/
int have_prefetcht1(int *p)
{
	int a;
	int x = 0;

	for(a = 0; a < BLOCK_SIZE; a += STEP_SIZE)
	{
		// issue the command for prefetching the next cache line into L2 cache
		// and it will load in parallel with performing calculations of a/(a+1);
		// when appropriate cell will be requested, it will be present in cache
		// and the processor won't have to wait for it to load
		_prefetcht1((char *)((char *)p + a + STEP_SIZE*6));

		// performing some calculations
		x += a/(a+1);

		// reading the next portion of cells
		x += *(int *)((char *)p + a + 0);
		x += *(int *)((char *)p + a + 4);
		x += *(int *)((char *)p + a + 8);
		x += *(int *)((char *)p + a + 12);
		x += *(int *)((char *)p + a + 16);
		x += *(int *)((char *)p + a + 20);
		x += *(int *)((char *)p + a + 24);
		x += *(int *)((char *)p + a + 28);
	}
return x;
}



main()
{	
	int *p;

	PRINT("= = = memory optimization using prefetch = = =\n");
	PRINT_TITLE;

	// allocating memory
	p = malloc(BLOCK_SIZE);
	
	A_BEGIN(0)
		no_prefetch(p);
	A_END(0)

	A_BEGIN(1)
		have_prefetchnta(p);
	A_END(1)

	A_BEGIN(2)
		have_prefetcht0(p);
	A_END(2)

	A_BEGIN(3)
		have_prefetcht1(p);
	A_END(3)

	Lx_OUT("prefetchnta",Ax_GET(0),Ax_GET(1));
	Lx_OUT("prefetcht0 ",Ax_GET(0),Ax_GET(2));
	Lx_OUT("prefetcht1 ",Ax_GET(0),Ax_GET(3));


}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?