2015-10-05 58 views
1

我有一個由許多tcl文件和過程組成的tcl環境,它們都在同一個命名空間下。根據輸入參數遞歸地開發該過程之一。 Synopsys的是:TCL中的遞歸過程調用

myproc *subcmd arg1* 

其中:

  • subcmd是一個子命令
  • ARG1是寄存器

ARG1可以是正常寄存器或所有註冊會導致提交子命令子命令給整體允許的註冊者。報告子命令爲get_status/get_delta/get_mask,最壞的情況由get_value子命令表示,該子命令繼承前面的子命令。如果提供寄存器所有,程序級堆棧如下:

myproc get_value all 
    myproc get_value reg1 
     myproc get_status reg1 
     myproc get_delta reg1 
     myproc get_mask reg1 
    myproc get_value reg2 
     myproc get_status reg2 
     myproc get_delta reg2 
     myproc get_mask reg2 
    ... 
    myproc get_value reg(n-1) 
     myproc get_status reg(n-1) 
     myproc get_delta reg(n-1) 
     myproc get_mask reg(n-1) 
    myproc get_value reg(n) 
     myproc get_status reg(n) 
     myproc get_delta reg(n) 
     myproc get_mask reg(n) 

這樣,我得到的最下面執行的執行速度慢。 我嘗試在互聯網上瀏覽以獲取有關如何提高性能而無結果的信息。一個可能的解決方案似乎是apply命令(lambda函數的父項),但我想這對我的目的來說太簡單了,其他方法可能會滿足我的問題。任何建議?

此刻,我想起與內聲明的過程本身:

eval {myproc *subcmd* arg1} 

編輯日誌和其他信息

我已經修改了代碼,以便跟蹤忠實於真實的。而且我公佈源代碼的一些片段,所以你可以看到如何在程序有效地叫:

# this is the call statement for 'all' register. 
# exp_opt1_list holds reg1, reg2, ..., reg(n) 
# the other parameter are not worth to explain, they are parsed above 
# *callprocname* is a procedure that return back the name of the call procedure which reside 1 level above. Practically this procedure is shared by identical procedures at upper level which differ only for the lists of registers. So callprocname gives the name of the upper procedure that originally called that core procedure 
foreach opt1_scan $exp_opt1_list($sub_cmd) { 
    if {($opt1 == "all") && $opt1_scan != "all" } { 
     set scan_result_list [string tolower [callprocname]] $sub_cmd $tag1 $tag2 $tag3 $opt1_scan $local_verbose -loop] 
     [...] 
    } 
} 

在跟進的get_該行*駐留是以下(即清理寄存器加上一個clear_delta):

if {[string equal -nocase GET_VALUE $sub_cmd]} { 
    set result [list] 
    lappend result [eval [list [string tolower [callprocname]] get_status $tag1 $tag2 $tag3 $opt1 $local_verbose]] 
    lappend result [eval [list [string tolower [callprocname]] get_delta $tag1 $tag2 $tag3 $opt1 $local_verbose]] 
        eval [list [string tolower [callprocname]] clr_delta $tag1 $tag2 $tag3 $opt1 $operation_verbose] 
    lappend result [eval [list [string tolower [callprocname]] get_mask $tag1 $tag2 $tag3 $opt1 $local_verbose]] 
} 

將第一代碼中繼狀態中的評論,也有很多嵌套的過程雖然他們大多是瑣碎或其他字都沒有計算需求。事實上,結構涉及到很多層次,比如6層(服務+核心),因爲一切都從調用核心的服務級別開始,如果涉及到註冊,那麼調用服務級別再次直接從核心,所以我們有服務 - >核心 - >服務 - >核心等等。

這個粗略的解釋是否足夠?

+0

恩,eval真的很慢。爲什麼不像普通程序那樣運行程序:'myproc * subcmd * arg1' –

+0

另外,向我們展示真正的代碼比僞代碼更有用。 –

+1

調用lambda並不會加快速度,但是您所描述的調用結構的類型不應該明顯變慢:可能還有其他一些因素導致其執行緩慢。使用真正的合奏命令而不是設置即興合奏界面可能會清除一些事情。 –

回答

0

你幾乎猜到了我的代碼是如何工作的,但我修改它以使它更接近我的代碼。


你的代碼看起來像這樣嗎?

proc myproc {subcmd reg} { 
    set n 5 
    switch -- $subcmd { 
     get_value { 
      if {$reg eq "all"} { 
       for {set i 1} {$i < $n} {incr i} { 
        myproc get_status reg$i 
        myproc get_delta reg$i 
        myproc get_mask reg$i 
       } 
      } 
     } 
     get_status { 
      if {$reg eq "all"} { 
       for {set i 1} {$i < $n} {incr i} { 
        myproc get_status reg$i 
       } 
      } else { 
       # do what get_status does with a single register 
      } 
     } 
     get_delta { 
      if {$reg eq "all"} { 
       for {set i 1} {$i < $n} {incr i} { 
        myproc get_delta reg$i 
       } 
      } else { 
       # do what get_delta does with a single register 
      } 
     } 
     get_mask { 
      if {$reg eq "all"} { 
       for {set i 1} {$i < $n} {incr i} { 
        myproc get_mask reg$i 
       } 
      } else { 
       # do what get_mask does with a single register 
      } 
     } 
    } 
} 

我在問,因爲我們真的需要弄清楚你的代碼是什麼樣子才能提醒你。

調用跟蹤上面的代碼:

myproc get_value all 
    myproc get_status reg1 
    myproc get_delta reg1 
    myproc get_mask reg1 
    myproc get_status reg2 
    myproc get_delta reg2 
    myproc get_mask reg2 
    myproc get_status reg3 
    myproc get_delta reg3 
    myproc get_mask reg3 
    myproc get_status reg4 
    myproc get_delta reg4 
    myproc get_mask reg4 

BTW我試圖「檔案」我的代碼以[時間],它只是似乎它緩慢歸因於對嵌套來電...

+0

我編輯了代碼,使其與我的類似... – MFrancone

+0

@MFrancone:好的,只有這個代碼並不真正與您的問題中的模擬呼叫跟蹤押韻。我添加了更新的通話跟蹤。 –