1. 程式人生 > >高效c語言 記憶體拷貝. 測試結果 rand, loop, operator= % in x86-64 SUSE

高效c語言 記憶體拷貝. 測試結果 rand, loop, operator= % in x86-64 SUSE

If you  use C++,C, when a  memory copy  is needed.   Please  Use    memcpy.    That will be very  very  very  fast!!!!

if you are wondering who is better between :

1+(int)(255.0*rand()/(RAND_MAX+1.0));

1+rand()%255;

1 + g_rand_int(m_rand)%255;

if you want to know the operator "%" is single instruction or multi instruction.

Next,   please  see the test results.

GTK+ 2.0.     x86-64   SUSE linux


odie:~/Desktop/xudong/workhome_gtk/performance_test # ./PerformanceTest
Time 1byte copy    : 984.65ms used for 100000 loops. Each loop 9846.48ns
Time 4byte copy    : 369.03ms used for 100000 loops. Each loop 3690.32ns
Time 8byte copy    : 206.85ms used for 100000 loops. Each loop 2068.53ns
Time g_memmove()   : 32.19ms used for 100000 loops. Each loop 321.85ns
Time rand()        : 775.47ms used for 10000000 loops. Each loop 77.55ns
Time rand()simple  : 769.42ms used for 10000000 loops. Each loop 76.94ns
Time G_rand        : 614.43ms used for 10000000 loops. Each loop 61.44ns
Time "="           : 115.55ms used for 10000000 loops. Each loop 11.55ns
Time %%2           : 128.83ms used for 10000000 loops. Each loop 12.88ns
Time pure loop     : 98.91ms used for 10000000 loops. Each loop 9.89ns


you see .    the g_memmove   function is   32 times  faster  than     for loop

here is  my   source code.

#include <gtk/gtk.h>
#include <glib.h>
#include <stdlib.h>

#define MAX_SIZE       1024

void Comput_Print_Result(gchar *str,guint loops,GTimeVal tStart);

int main(int argc,char **argv)
{ 
	guchar buf111[MAX_SIZE];
	guchar buf222[MAX_SIZE];
	GTimeVal tstart;
	guint i,j;
	guint testTimes = 100000;
	


	//init data
	for(i=0;i<MAX_SIZE;i++)
	{
		buf111[i] = 1;
		buf222[i] = 2;
	}


//begin test:   1byte  copy
	g_get_current_time(&tstart);//start time
	for(j=0;j<testTimes;j++)
		for(i=0;i<MAX_SIZE;i++)
			buf111[i] = buf222[i];
	Comput_Print_Result("1byte copy    ",testTimes,tstart);


//test start:   4bytes  copy
	guint* srcInt = (guint*)buf222;
	guint* dstInt = (guint*)buf111;
	g_get_current_time(&tstart);//start time
	for(j=0;j<testTimes;j++)
		for(i=0;i<MAX_SIZE/4;i++)
			dstInt[i] = srcInt[i];
	Comput_Print_Result("4byte copy    ",testTimes,tstart);
                             

//test start:   8bytes  copy
	guint64* src64 = (guint64*)buf222;
	guint64* dst64 = (guint64*)buf111;
	g_get_current_time(&tstart);//start time
	for(j=0;j<testTimes;j++)
		for(i=0;i<MAX_SIZE/8;i++)
			dst64[i] = src64[i];
	Comput_Print_Result("8byte copy    ",testTimes,tstart);



	//init data
	for(i=0;i<MAX_SIZE;i++)
	{
		buf111[i] = 1;
		buf222[i] = 2;
	}


//test start:   g_memmove()
	g_get_current_time(&tstart);//start time
	for(j=0;j<testTimes;j++)
		g_memmove((void *)buf111,(void *)buf222, MAX_SIZE);
	Comput_Print_Result("g_memmove()   ",testTimes,tstart);

	//check data
	for(i=0;i<MAX_SIZE;i++)
		if(buf111[i] != buf222[i])
			g_print("mem copy failed\n");

	       




	GRand      *m_rand;
	m_rand = g_rand_new();
	guchar color;
	guint testTimes2 = 10000000;
//test start:   rand()
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++)
		color = 1+(int)(255.0*rand()/(RAND_MAX+1.0));
	Comput_Print_Result("rand()        ",testTimes2,tstart);

//test start:   rand() simple
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++)
		color = 1+rand()%255;
	Comput_Print_Result("rand()simple  ",testTimes2,tstart);

//test start:   Grand
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++)
		color = 1 + g_rand_int(m_rand)%255;
	Comput_Print_Result("G_rand        ",testTimes2,tstart);

//test start:   "="
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++)
		color = 2;
	Comput_Print_Result("\"=\"           ",testTimes2,tstart);

//test start:   "%"
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++)
		color = i%2;
	Comput_Print_Result("%%2           ",testTimes2,tstart);

//test start:   noting
	g_get_current_time(&tstart);//start time
	for(i=0;i<testTimes2;i++);
	Comput_Print_Result("pure loop     ",testTimes2,tstart);


	return 0;
}




void Comput_Print_Result(gchar *str,guint loops,GTimeVal tStart)
{
	GTimeVal tEnd;
	g_get_current_time(&tEnd);
	gfloat time_msec = (1000000.00*(tEnd.tv_sec - tStart.tv_sec)+ tEnd.tv_usec-tStart.tv_usec)/1000;
	gfloat time_each = time_msec / loops * 1000000;
	g_print("Time %s: %.2fms used for %d loops. Each loop %.2fns\n",str,time_msec,loops,time_each);
}


here is my  makefile

CC=gcc
PROG_NAME=PerformanceTest
INCS=
SRCS=PerformanceTest.c

#from xx.c to xx.o
OBJS=${SRCS:.c=.o}

#the libs for compiling GTK program
LIBS=gtk+-2.0 

#----------------do not edit this below
CFLAGS=`pkg-config --cflags ${LIBS}` -g -Wall
LDFLAGS=`pkg-config --libs ${LIBS}` -g -Wall
all: ${PROG_NAME}

${PROG_NAME}:${OBJS}
	${CC} -o ${PROG_NAME} ${OBJS} ${LDFLAGS}

${OBJS}:${INCS}

.c.o:
	${CC} -c {1}lt; ${CFLAGS}
clean:
	rm -f *.o ${PROG_NAME}
rebuild: clean all



相關推薦

高效c語言 記憶體拷貝. 測試結果 rand, loop, operator= % in x86-64 SUSE

If you  use C++,C, when a  memory copy  is needed.   Please  Use    memcpy.    That will be very  very  very  fast!!!! if you are wonderi

C語言——記憶體消耗測試程式

/*這是一個消耗記憶體的測試c程式*/ /* 用法: *  ./test-mem arg1 arg2 arg3 * arg1表示每秒分配的記憶體數量(單位M) * arg2表示總共分配多少記憶體 * arg3表示程式存活多久(預設300秒) */ # include &l

C語言跳水比賽預測結果

轉換 turn 精簡 print system tdi ++ col pre 5位運動員參加了10米臺跳水比賽,有人讓他們預測比賽結果A選手說:B第二,我第三;B選手說:我第二,E第四;C選手說:我第一,D第二;D選手說:C最後,我第三;E選手說:我第四,A第一;比賽結束後

C語言--字串拷貝、字串查詢、字串比較、字串擷取

 在實際的應用當中,字元和字串的操作是最常用的技能。總結下來,提升能力。 一、字串拷貝 1、memcpy 2、strcpy 區別 二、字串查詢 三、字串比較 四、字串擷取 1、一種簡單而又機智的方法–strncpy  strncpy函

C語言拷貝傳遞機制

當引數是常量,變數,或表示式時,傳遞的資料就是這些資料物件所具有的內容,這種方式稱為數值引數傳遞方式(簡稱傳值方式)。如果函式呼叫時所傳遞的實參是資料物件在記憶體中的儲存單元的首地址值,這種方式稱為地址值引數傳遞方式(簡稱傳地址方式)。陣列引數和指標引數使用的就是地址值傳遞呼叫方式。 無論函式呼叫時傳遞的是

c語言--記憶體學習總結

變數在記憶體中的形式 1.定義 作用域 :變數聲明後時,只有在一定區域內才能被訪問 儲存期:程式中變數的儲存終止時間 連結: 連結屬性是為了說明在不同檔案中出現的相同識別符號應該如何處理 作用域(分類) 塊作用域 函式作用域

C語言記憶體分配規則

動態儲存區(堆) malloc動態分配在heap堆區。 程式設計師自己分配自己釋放。 動態儲存區(棧) 自動變數、const變數在stack棧區。 系統自動分配釋放。 靜態儲存區 extern全域性變數在static靜態儲存區。一旦分配,不會被回收,可讀可寫 程式程式

c語言記憶體的理解

      首先如圖記憶體分四區  棧區(stack)—由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。 堆區(heap)—一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時

C語言記憶體區域

記憶體 變數 變數型別 作用域 生命週期 儲存位置 區域性變數 函式內部 從變數建立到函式結束 棧區 全域性變數

C語言記憶體管理

記憶體管理的基本概念 分析C語言記憶體的分佈先從Linux下可執行的C程式入手。現在有一個簡單的C源程式hello.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 int var1 = 1; 4

C語言 記憶體分配和static關鍵字

C語言記憶體分配機制 (1)程式碼區(text segment)。.text程式碼區指令根據程式設計流程依次執行,對於順序指令,則只會執行一次(每個程序),如果反覆,則需要使用跳轉指令,如果進行遞迴,則需要藉助棧來實現。程式碼區的指令中包括操作碼和要操作的物件(

繪製數字濾波器的頻域響應,對比C語言與MATLAB的結果

設傳遞函式H(z)H(z)H(z)的分子分母系數為: b=[0.0563 -0.0009 -0.0009 0.0563];%分子 a=[1.0000 -2.1291 1.7834 -0.5435];%分母 MATLAB程式碼 b=[

C語言--記憶體(說法二)

原始碼編譯之後,分為兩個狀態:儲存時、執行時。 儲存時  在linux環境下,可以對編譯好的二進位制檔案執行size指令可以獲取該二進位制可執行檔案的結構情況: # size test.out 程式碼區 全域性初始化資料區/靜態資料區

C語言--記憶體(說法一)

轉載自:https://www.cnblogs.com/yif1991/p/5049638.html  在計算機系統,特別是嵌入式系統中,記憶體資源是非常有限的。尤其對於移動端開發者來說,硬體資源的限制使得其在程式設計中首要考慮的問題就是如何有效地管理記憶體資源。本文是作者在學習C語言記

C 語言記憶體分配函式

1、ANSI C 中的記憶體空間分配函式 ANSI C 中有 3 個分配記憶體的函式:malloc,calloc,realloc。 函式原型: #include <stdlib.h> void *malloc(size_t size); void

關於C語言記憶體對齊,提高定址效率問題

前言: 計算機的記憶體都是以位元組為單位來劃分的,CPU一般都是通過地址匯流排來訪問記憶體的,一次能處理幾個位元組,就命令地址匯流排去訪問幾個位元組,32位的CPU一次能處理4個位元組,就命令地址匯流排一次讀取4個位元組,讀少了浪費主頻,讀多了也處理不了。64位的CPU一般

常見C語言記憶體錯誤

前言 C語言強大的原因之一在於幾乎能掌控所有的細節,包括對記憶體的處理,什麼時候使用記憶體,使用了多少記憶體,什麼時候該釋放記憶體,這都在程式設計師的掌控之中。而不像Java中,程式設計師是不需要花太多精力去處理垃圾回收的事情,因為有JVM在背後做著這一切。但是同樣地,能力越大,責任越大。不恰當地操作記憶體

c語言 記憶體四區

1.棧區(stack):由編譯器操作,存放函式的引數值,區域性變數,資料結構就是棧. 2.堆區(heap):由new``delete``free``malloc來操作,資料結構類似於連結串列 3.資

c語言記憶體對齊與#pragma pack(n)

一、什麼是記憶體對齊,為什麼要記憶體對齊  現在計算機記憶體空間都是按照byte位元組劃分的,理論上講對任何型別的變數的訪問可以從任何地址開始,但實際情況是在訪問特定型別變數的時候經常在特定的記憶體地址上訪問,這就需要各種資料型別按照一定的規則在空間上排列,而不是一個接一個