[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:389

From: ko1 atdot.net
Date: 6 Sep 2006 22:44:34 +0900
Subject: [yarv-diff:389] r556 - branches/parallel

Author: ko1
Date: 2006-09-06 22:44:33 +0900 (Wed, 06 Sep 2006)
New Revision: 556

Modified:
   branches/parallel/ChangeLog
   branches/parallel/thread.c
   branches/parallel/yarvcore.h
Log:
	* thread.c : add CPU control feature for multi-CPU/Core

	* yarvcore.h : ditto



Modified: branches/parallel/ChangeLog
===================================================================
--- branches/parallel/ChangeLog	2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/ChangeLog	2006-09-06 13:44:33 UTC (rev 556)
@@ -4,6 +4,13 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-09-06(Wed) 22:43:04 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* thread.c : add CPU control feature for multi-CPU/Core
+
+	* yarvcore.h : ditto
+
+
 2006-09-05(Tue) 22:16:37 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* thread.c : add rb_thread_write

Modified: branches/parallel/thread.c
===================================================================
--- branches/parallel/thread.c	2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/thread.c	2006-09-06 13:44:33 UTC (rev 556)
@@ -60,6 +60,7 @@
 static const VALUE eTerminateSignal = INT2FIX(1);
 
 static int system_working = 1;
+static int profile_conflict = 0;
 
 inline static void
 st_delete_wrap(st_table * table, VALUE key)
@@ -136,11 +137,10 @@
 #define DEC_WAIT_THREAD(vm) ((vm)->num_wait_threads--)
 #endif
 
-static int profile_confilict;
 static void __attribute__((destructor))
      pr_show(void)
 {
-    fprintf(stderr, "profile_confilict: %d\n", profile_confilict);
+    // fprintf(stderr, "profile_conflict: %d\n", profile_conflict);
 }
 
 static int g_spinlock_count;
@@ -160,10 +160,14 @@
     else {
 	thread_debug("rb_thread_global_lock_acquire: try acquire (%p) --> \n",
 		     vm->lock_owner_thread);
-	
+
 	if (native_mutex_trylock(&vm->global_interpreter_lock) == EBUSY) {
 	    int i;
+	    th->profile_conflict++;
+	    profile_conflict++;
 	    for (i=0; i<g_spinlock_count; i++) {
+		th->profile_conflict++;
+		profile_conflict++;
 		if (native_mutex_trylock(&vm->global_interpreter_lock) == 0) {
 		    goto gotlock;
 		}
@@ -172,11 +176,9 @@
 		}
 		native_thread_yield();
 	    }
-	    
+
 	    yarv_save_machine_context(th);
 
-	    profile_confilict++;
-	    
 	    native_mutex_lock(&vm->gc_lock);
 	    {
 		INC_WAIT_THREAD(vm);
@@ -185,7 +187,7 @@
 		}
 	    }
 	    native_mutex_unlock(&vm->gc_lock);
-	    
+
 	    native_mutex_lock(&vm->global_interpreter_lock);
 	    thread_debug("rb_thread_global_lock_acquire: <-- done (lock)\n");
 
@@ -1825,7 +1827,66 @@
     fclose(fp);
 }
 
+#define TS_CONFLICT 10000
+
+#if HAVE_SCHED_SETAFFINITY
+
 static void
+set_cpu_cnt(yarv_thread_t *th, int num)
+{
+    cpu_set_t mask;
+    int i;
+    
+    __CPU_ZERO(&mask);
+    for (i=0; i<num; i++) {
+	__CPU_SET(i, &mask);
+    }
+    if (pthread_setaffinity_np(th->thread_id,  sizeof(cpu_set_t), &mask) != 0) {
+	rb_bug("sched_setaffinity error: %d\n", errno);
+    }
+
+    if (0) {
+	/* for debug */
+	pthread_getaffinity_np(th->thread_id, sizeof(cpu_set_t), &mask);
+	for (i=0; i<8; i++) {
+	    fprintf(stderr, "%d: %d\n", i, __CPU_ISSET(i, &mask));
+	}
+    }
+}
+
+static int
+set_cpu_cnt_i(st_data_t key, st_data_t val, int is_clear)
+{
+    VALUE thval = key;
+    yarv_thread_t *th;
+    int i;
+    GetThreadPtr(thval, th);
+//   fprintf(stderr, ">> %p: %d\n", th, th->profile_conflict);
+
+// #define thread_debug(x, y) fprintf(stderr, x, y)
+    if (th->profile_conflict > 1000 && !is_clear) {
+	if (th->profile_conflict_toggle == 0) {
+	    thread_debug("cpu down: %d\n", th->profile_conflict);
+	    set_cpu_cnt(th, 1);
+	    //th->profile_conflict_limited_count = 10;
+	    th->profile_conflict_toggle = 1;
+	}
+    }
+    else {
+	if (th->profile_conflict_toggle == 1) {
+	    thread_debug("cpu up: %d\n", th->profile_conflict);
+	    set_cpu_cnt(th, 8);
+	    //th->profile_conflict_limited_count = 0;
+	    th->profile_conflict_toggle = 0;
+	}
+    }
+// #define thread_debug if (0) printf
+    th->profile_conflict = 0;
+    return ST_CONTINUE;
+}
+#endif
+
+static void
 timer_function(void)
 {
     yarv_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */
@@ -1851,6 +1912,54 @@
 	prof_in_r++;
     }
 #endif
+
+
+#if 1
+#if HAVE_SCHED_SETAFFINITY
+    {
+	static int prev_confilict;
+	static int cnt = 100;
+
+	if (cnt-- < 0) {
+	    st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t)1);
+	    cnt = 100;
+	}
+	else {
+	    if (profile_conflict - prev_confilict > 10000) {
+		st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t)0);
+	    }
+	}
+	prev_confilict = profile_conflict;
+    }
+#elif 0
+    {
+	static int prev_confilict;
+	static int toggle = 1;
+	static int buff = 0;
+	int d = profile_conflict - prev_confilict;
+
+	//fprintf(stderr, "%d\n", d);
+	if (d > TS_CONFLICT) {
+	    if (toggle == 1 && buff-- < 0) {
+		thread_debug("cpu down: %d\n", d);
+		st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t) 1);
+		toggle = 0;
+		buff = 100;
+	    }
+	}
+	else {
+	    if (toggle == 0 && buff-- < 0) {
+		thread_debug("cpu up: %d\n", d);
+		st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t) 2);
+		toggle = 1;
+		buff = 0;
+	    }
+	}
+	prev_confilict = profile_conflict;
+    }
+#endif
+#endif
+
 }
 
 /*
@@ -2303,7 +2412,7 @@
 	g_spinlock_count = atoi(env);
     }
     else {
-	g_spinlock_count = 100;
+	g_spinlock_count = 50;
     }
     
     rb_disable_interrupt(); /* only timer thread recieve signal */

Modified: branches/parallel/yarvcore.h
===================================================================
--- branches/parallel/yarvcore.h	2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/yarvcore.h	2006-09-06 13:44:33 UTC (rev 556)
@@ -470,6 +470,11 @@
     /* misc */
     int method_missing_reason;
     int abort_on_exception;
+    
+    int profile_conflict;
+    int profile_conflict_toggle;
+    int profile_conflict_limited_count;
+    
     struct re_registers regs;
 } yarv_thread_t;
 


--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]