STM32單片機uCOS-Ⅲ系統10 內存管理

目錄

一、內存管理的基本概念

二、內存管理的運作機制

三、內存管理的應用場景

四、內存管理函數接口講解

1、內存池創建函數?OSMemCreate()

2、內存申請函數 OSMemGet()

3、內存釋放函數?OSMemPut()

五、實現


一、內存管理的基本概念

????????在計算系統中,變量、中間數據一般存放在系統存儲空間中,只有在實際使用時才將它們從存儲空間調入到中央處理器內部進行運算。通常存儲空間可以分為兩種:內部存儲空間和外部存儲空間。內部存儲空間訪問速度比較快,能夠按照變量地址隨機地訪問,也就是我們通常所說的 RAM(隨機存儲器),或電腦的內存;而外部存儲空間內所保存的內容相對來說比較固定,即使掉電后數據也不會丟失,可以把它理解為電腦的硬盤。在這一章中我們主要討論內部存儲空間(RAM)的管理——內存管理。

????????在嵌入式系統設計中,內存分配應該是根據所設計系統的特點來決定選擇使用動態內存分配還是靜態內存分配算法,一些可靠性要求非常高的系統應選擇使用靜態的,而普通的業務系統可以使用動態來提高內存使用效率。靜態可以保證設備的可靠性但是需要考慮內存上限,內存使用效率低,而動態則是相反。

????????uCOS 的內存管理是采用內存池的方式進行管理,也就是創建一個內存池,靜態劃分一大塊連續空間作為內存管理的空間,里面劃分為很多個內存塊,我們在使用的時候就從這個內存池中獲取一個內存塊,使用完畢的時候用戶可以將其放回內存池中,這樣子就不會導致內存碎片的產生。

????????uCOS 內存管理模塊管理用于系統中內存資源,它是操作系統的核心模塊之一, 主要包括內存池的創建、分配以及釋放。

????????很多人會有疑問,什么不直接使用 C 標準庫中的內存管理函數呢?在電腦中我們可以用 malloc()和 free()這兩個函數動態的分配內存和釋放內存。但是,在嵌入式實時操作系統中,調用 malloc()和 free()卻是危險的,原因有以下幾點:

  • 這些函數在小型嵌入式系統中并不總是可用的,小型嵌入式設備中的 RAM 不足。
  • 它們的實現可能非常的大,占據了相當大的一塊代碼空間。
  • 他們幾乎都不是安全的。
  • 它們并不是確定的,每次調用這些函數執行的時間可能都不一樣。
  • 它們有可能產生碎片。
  • 這兩個函數會使得鏈接器配置得復雜。
  • 如果允許堆空間的生長方向覆蓋其他變量占據的內存,它們會成為 debug 的災難。

????????在一般的實時嵌入式系統中,由于實時性的要求,很少使用虛擬內存機制。所有的內存都需要用戶參與分配,直接操作物理內存,所分配的內存不能超過系統的物理內存,所有的系統堆棧的管理,都由用戶自己管理。

????????同時,在嵌入式實時操作系統中,對內存的分配時間要求更為苛刻,分配內存的時間必須是確定的。一般內存管理算法是根據需要存儲的數據的長度在內存中去尋找一個與這段數據相適應的空閑內存塊,然后將數據存儲在里面, 而尋找這樣一個空閑內存塊所耗費的時間是不確定的,因此對于實時系統來說,這就是不可接受的,實時系統必須要保證內存塊的分配過程在可預測的確定時間內完成,否則實時任務對外部事件的響應也將變得不可確定。

????????在嵌入式系統中,內存是十分有限而且是十分珍貴的,用一塊內存就少了一塊內存,而在分配中隨著內存不斷被分配和釋放,整個系統內存區域會產生越來越多的碎片,因為在使用過程中,申請了一些內存,其中一些釋放了,導致內存空間中存在一些小的內存塊,它們地址不連續,不能夠作為一整塊的大內存分配出去,所以一定會在某個時間,系統已經無法分配到合適的內存了,導致系統癱瘓。其實系統中實際是還有內存的,但是因為小塊的內存的地址不連續,導致無法分配成功,所以我們需要一個優良的內存分配算法來避免這種情況的出現。

????????所以 uCOS 提供的內存分配算法是只允許用戶分配固定大小的內存塊,當使用完成就將其放回內存池中,這樣子分配效率極高,時間復雜度是 O(1),也就是一個固定的時間常數,并不會因為系統內存的多少而增加遍歷內存塊列表的時間, 并且還不會導致內存碎片的出現,但是這樣的內存分配機制會導致內存利用率的下降以及申請內存大小的限制

二、內存管理的運作機制

????????內存池(Memory Pool)是一種用于分配大量大小相同的內存對象的技術,它可以極大加快內存分配/釋放的速度。

????????在系統編譯的時候,編譯器就靜態劃分了一個大數組作為系統的內存池,然后在初始化的時候將其分成大小相等的多個內存塊,內存塊直接通過鏈表連接起來(此鏈表也稱為空閑內存塊列表)。每次分配的時候,從空閑內存塊列表中取出表頭上第一個內存塊,提供給申請者。物理內存中允許存在多個大小不同的內存池,每一個內存池又由多個大小相同的空閑內存塊組成。

???????? 我們必須先創建內存池才能去使用內存池里面的內存塊,在創建的時候,我們必須定義一個內存池控制塊,然后進行相關初始化,內存控制塊的參數包括內存池名稱,內存池起始地址,內存塊大小, 內存塊數量等信息, 在以后需要從內存池取出內存塊或者釋放內存塊的時候,我們只需根據內存控制塊的信息就能很輕易做到。

三、內存管理的應用場景

????????首先,在使用內存分配前,必須明白自己在做什么,這樣做與其他的方法有什么不同,特別是會產生哪些負面影響,在自己的產品面前,應當選擇哪種分配策略。

????????內存管理的主要工作是動態劃分并管理用戶分配好的內存區間,主要是在用戶需要使用大小不等的內存塊的場景中使用, 當用戶需要分配內存時,可以通過操作系統的內存申請函數索取指定大小內存塊,一旦使用完畢,通過動態內存釋放函數歸還所占用內存,使之可以重復使用(heap_1.c 的內存管理除外)。

例如我們需要定義一個 float 型數組: floatArr[];

????????但是,在使用數組的時候,總有一個問題困擾著我們:數組應該有多大?在很多的情況下,你并不能確定要使用多大的數組,可能為了避免發生錯誤你就需要把數組定義得足夠大。即使你知道想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程序,擴大數組的存儲范圍。這種分配固定大小的內存分配方法稱之為靜態內存分配。這種內存分配的方法存在比較嚴重的缺陷,在大多數情況下會浪費大量的內存空間,在少數情況下,當你定義的數組不夠大時,可能引起下標越界錯誤,甚至導致嚴重后果。

????????uCOS 將系統靜態分配的大數組作為內存池,然后進行內存池的初始化,然后分配固定大小的內存塊。

????????注意: uCOS 也不能很好解決這種問題,因為內存塊的大小是固定的,無法解決這種彈性很大的內存需求,只能按照最大的內存塊進行分配。但是 uCOS 的內存分配能解決內存利用率的問題,在不需要使用內存的時候,將內存釋放到內存池中,讓其他任務能正常使用該內存塊。

四、內存管理函數接口講解

1、內存池創建函數?OSMemCreate()

????????在使用內存池的時候首先要創建一個內存池,需要用戶靜態分配一個數組空間作為系統的內存池,且用戶還需定義一個內存控制塊。創建內存池后,任務才可以通過系統的內存 申 請 、 釋 放函數從內存池中申請或釋放內存,uCOS提供內存池創建函數OSMemCreate()。

2、內存申請函數 OSMemGet()

????????這個函數用于申請固定大小的內存塊, 從指定的內存池中分配一個內存塊給用戶使用,該內存塊的大小在內存池初始化的時候就已經決定的。如果內存池中有可用的內存塊,則從內存池的空閑內存塊列表上取下一個內存塊并且返回對應的內存地址;如果內存池中已經沒有可用內存塊,則返回 0 與對應的錯誤代碼 OS_ERR_MEM_NO_FREE_BLKS。

3、內存釋放函數?OSMemPut()

????????嵌入式系統的內存對我們來說是十分珍貴的, 任何內存塊使用完后都必須被釋放,否則會造成內存泄露,導致系統發生致命錯誤。 uCOS 提供了 OSMemPut()函數進行內存的釋放管理,使用該函數接口時,根據指定的內存控制塊對象,將內存塊插入內存池的空閑內存塊列表中,然后增加該內存池的可用內存塊數目。

五、實現

#include <includes.h>
#include <string.h>OS_MEM  mem;                    //聲明內存管理對象
uint8_t ucArray [ 3 ] [ 20 ];   //聲明內存分區大小static  OS_TCB   AppTaskStartTCB;    //任務控制塊static  OS_TCB   AppTaskPostTCB;
static  OS_TCB   AppTaskPendTCB;static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];       //任務堆棧static  CPU_STK  AppTaskPostStk [ APP_TASK_POST_STK_SIZE ];
static  CPU_STK  AppTaskPendStk [ APP_TASK_PEND_STK_SIZE ];static  void  AppTaskStart  (void *p_arg);               //任務函數聲明static  void  AppTaskPost   ( void * p_arg );
static  void  AppTaskPend   ( void * p_arg );int  main (void)
{OS_ERR  err;OSInit(&err);                                                           //初始化 uC/OS-III/* 創建起始任務 */OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,                            //任務控制塊地址(CPU_CHAR   *)"App Task Start",                            //任務名稱(OS_TASK_PTR ) AppTaskStart,                               //任務函數(void       *) 0,                                          //傳遞給任務函數(形參p_arg)的實參(OS_PRIO     ) APP_TASK_START_PRIO,                        //任務的優先級(CPU_STK    *)&AppTaskStartStk[0],                         //任務堆棧的基地址(CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10,               //任務堆棧空間剩下1/10時限制其增長(CPU_STK_SIZE) APP_TASK_START_STK_SIZE,                    //任務堆棧空間(單位:sizeof(CPU_STK))(OS_MSG_QTY  ) 5u,                                         //任務可接收的最大消息數(OS_TICK     ) 0u,                                         //任務的時間片節拍數(0表默認值OSCfg_TickRate_Hz/10)(void       *) 0,                                          //任務擴展(0表不擴展)(OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任務選項(OS_ERR     *)&err);                                       //返回錯誤類型OSStart(&err);                                                          //啟動多任務管理(交由uC/OS-III控制)}static  void  AppTaskStart (void *p_arg)
{CPU_INT32U  cpu_clk_freq;CPU_INT32U  cnts;OS_ERR      err;(void)p_arg;BSP_Init();                                                 //板級初始化CPU_Init();                                                 //初始化 CPU 組件(時間戳、關中斷時間測量和主機名)cpu_clk_freq = BSP_CPU_ClkFreq();                           //獲取 CPU 內核時鐘頻率(SysTick 工作時鐘)cnts = cpu_clk_freq / (CPU_INT32U)OSCfg_TickRate_Hz;        //根據用戶設定的時鐘節拍頻率計算 SysTick 定時器的計數值OS_CPU_SysTickInit(cnts);                                   //調用 SysTick 初始化函數,設置定時器計數值和啟動定時器Mem_Init();                                                 //初始化內存管理組件(堆內存池和內存池表)#if OS_CFG_STAT_TASK_EN > 0u                                    //如果使能(默認使能)了統計任務OSStatTaskCPUUsageInit(&err);                               //計算沒有應用任務(只有空閑任務)運行時 CPU 的(最大)
#endif                                                          //容量(決定 OS_Stat_IdleCtrMax 的值,為后面計算 CPU //使用率使用)。CPU_IntDisMeasMaxCurReset();                                //復位(清零)當前最大關中斷時間/* 創建內存管理對象 mem */OSMemCreate ((OS_MEM      *)&mem,             //指向內存管理對象(CPU_CHAR    *)"Mem For Test",   //命名內存管理對象(void        *)ucArray,          //內存分區的首地址(OS_MEM_QTY   )3,                //內存分區中內存塊數目(OS_MEM_SIZE  )20,               //內存塊的字節數目(OS_ERR      *)&err);            //返回錯誤類型/* 創建 AppTaskPost 任務 */OSTaskCreate((OS_TCB     *)&AppTaskPostTCB,                             //任務控制塊地址(CPU_CHAR   *)"App Task Post",                             //任務名稱(OS_TASK_PTR ) AppTaskPost,                                //任務函數(void       *) 0,                                          //傳遞給任務函數(形參p_arg)的實參(OS_PRIO     ) APP_TASK_POST_PRIO,                         //任務的優先級(CPU_STK    *)&AppTaskPostStk[0],                          //任務堆棧的基地址(CPU_STK_SIZE) APP_TASK_POST_STK_SIZE / 10,                //任務堆棧空間剩下1/10時限制其增長(CPU_STK_SIZE) APP_TASK_POST_STK_SIZE,                     //任務堆棧空間(單位:sizeof(CPU_STK))(OS_MSG_QTY  ) 5u,                                         //任務可接收的最大消息數(OS_TICK     ) 0u,                                         //任務的時間片節拍數(0表默認值OSCfg_TickRate_Hz/10)(void       *) 0,                                          //任務擴展(0表不擴展)(OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任務選項(OS_ERR     *)&err);                                       //返回錯誤類型/* 創建 AppTaskPend 任務 */OSTaskCreate((OS_TCB     *)&AppTaskPendTCB,                             //任務控制塊地址(CPU_CHAR   *)"App Task Pend",                             //任務名稱(OS_TASK_PTR ) AppTaskPend,                                //任務函數(void       *) 0,                                          //傳遞給任務函數(形參p_arg)的實參(OS_PRIO     ) APP_TASK_PEND_PRIO,                         //任務的優先級(CPU_STK    *)&AppTaskPendStk[0],                          //任務堆棧的基地址(CPU_STK_SIZE) APP_TASK_PEND_STK_SIZE / 10,                //任務堆棧空間剩下1/10時限制其增長(CPU_STK_SIZE) APP_TASK_PEND_STK_SIZE,                     //任務堆棧空間(單位:sizeof(CPU_STK))(OS_MSG_QTY  ) 50u,                                        //任務可接收的最大消息數(OS_TICK     ) 0u,                                         //任務的時間片節拍數(0表默認值OSCfg_TickRate_Hz/10)(void       *) 0,                                          //任務擴展(0表不擴展)(OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), //任務選項(OS_ERR     *)&err);                                       //返回錯誤類型OSTaskDel ( & AppTaskStartTCB, & err );                     //刪除起始任務本身,該任務不再運行}static  void  AppTaskPost ( void * p_arg )
{OS_ERR      err;char *   p_mem_blk;uint32_t ulCount = 0;(void)p_arg;while (DEF_TRUE) {                                        //任務體/* 向 mem 獲取內存塊 */p_mem_blk = OSMemGet ((OS_MEM      *)&mem,              //指向內存管理對象(OS_ERR      *)&err);             //返回錯誤類型sprintf ( p_mem_blk, "%d", ulCount ++ );                //向內存塊存取計數值/* 發布任務消息到任務 AppTaskPend */OSTaskQPost ((OS_TCB      *)&AppTaskPendTCB,            //目標任務的控制塊(void        *)p_mem_blk,                  //消息內容的首地址(OS_MSG_SIZE  )strlen ( p_mem_blk ),       //消息長度(OS_OPT       )OS_OPT_POST_FIFO,           //發布到任務消息隊列的入口端(OS_ERR      *)&err);                      //返回錯誤類型OSTimeDlyHMSM ( 0, 0, 1, 0, OS_OPT_TIME_DLY, & err );   //每20ms發送一次}}static  void  AppTaskPend ( void * p_arg )
{OS_ERR         err;OS_MSG_SIZE    msg_size;CPU_TS         ts;CPU_INT32U     cpu_clk_freq;CPU_SR_ALLOC();char * pMsg;(void)p_arg;cpu_clk_freq = BSP_CPU_ClkFreq();                  //獲取CPU時鐘,時間戳是以該時鐘計數while (DEF_TRUE) {                                           //任務體/* 阻塞任務,等待任務消息 */pMsg = OSTaskQPend ((OS_TICK        )0,                    //無期限等待(OS_OPT         )OS_OPT_PEND_BLOCKING, //沒有消息就阻塞任務(OS_MSG_SIZE   *)&msg_size,            //返回消息長度(CPU_TS        *)&ts,                  //返回消息被發布的時間戳(OS_ERR        *)&err);                //返回錯誤類型ts = OS_TS_GET() - ts;                            //計算消息從發布到被接收的時間差LED1_TOGGLE;                                //切換LED1的亮滅狀態OS_CRITICAL_ENTER();                              //進入臨界段,避免串口打印被打斷printf ( "\r\n接收到的消息的內容為:%s,長度是:%d字節。",pMsg, msg_size );  printf ( "\r\n任務消息從被發布到被接收的時間差是%dus\r\n",ts / ( cpu_clk_freq / 1000000 ) );  OS_CRITICAL_EXIT();                               //退出臨界段/* 退還內存塊 */OSMemPut ((OS_MEM  *)&mem,                        //指向內存管理對象(void    *)pMsg,                        //內存塊的首地址(OS_ERR  *)&err);		                    //返回錯誤類型}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73127.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73127.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73127.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

考研課程安排(自用)

文章目錄 408數據結構&#xff08;王道&#xff09;計算機組成原理&#xff08;王道&#xff09;操作系統&#xff08;王道&#xff09;計算機網絡&#xff08;湖科大版&#xff09; 數學一高等數學&#xff08;微積分&#xff09;線性代數和概率論 408 數據結構&#xff08;王…

ultraiso制作u盤啟動

UltraISO制作U盤啟動盤的方法 UltraISO是一款功能強大的工具&#xff0c;可以幫助用戶將ISO鏡像文件寫入U盤&#xff0c;從而制作成可啟動的系統安裝盤。以下是詳細的步驟和注意事項&#xff1a; 1. ?準備工作? ?硬件準備?&#xff1a;一個容量至少為8GB的U盤&#xff0…

C語言-發布訂閱模式詳解與實踐

文章目錄 C語言發布訂閱模式詳解與實踐1. 什么是發布訂閱模式&#xff1f;2. 為什么需要發布訂閱模式&#xff1f;3. 實際應用場景4. 代碼實現4.1 UML 關系圖4.2 頭文件 (pubsub.h)4.3 實現文件 (pubsub.c)4.4 使用示例 (main.c) 5. 代碼分析5.1 關鍵設計點5.2 實現特點 6. 編譯…

藍橋杯2023年第十四屆省賽真題-異或和之差

題目來自DOTCPP&#xff1a; 思路&#xff1a; 什么是異或和&#xff1f; ①題目要求我們選擇兩個不相交的子段&#xff0c;我們可以枚舉一個分界線i&#xff0c;子段1在 i 的左邊&#xff0c; 子段2在 i 的右邊&#xff0c;分別找到子段1和子段2的最大值、最小值。 ②怎么確…

Linux作業2——有關文件系統權限的練習

1、創建/www目錄&#xff0c;在/www目錄下新建name和https目錄&#xff0c;在name和https目錄下分別創建一個index.html文件&#xff0c;name下面的index.html文件中包含當前主機的主機名&#xff0c;https目錄下的index.html文件中包含當前主機的ip地址。 #創建/www目錄&…

leeCode 70. 爬樓梯

假設你正在爬樓梯。需要 n 階你才能到達樓頂。 每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢&#xff1f; 示例 1&#xff1a; 輸入&#xff1a;n 2 輸出&#xff1a;2 解釋&#xff1a;有兩種方法可以爬到樓頂。 1. 1 階 1 階 2. 2 階 示例 2&#x…

算法題(105):小貓爬山

審題&#xff1a; 本題需要我們找出將n個小貓放在有限重的纜車上運下山所需的最小纜車數 時間復雜度分析&#xff1a;本題的數據量小于等于18&#xff0c;所以我們在做好剪枝的前提下可以使用深度優先搜索解題 思路&#xff1a; 方法一&#xff1a;dfs 搜索策略&#xff1a;將小…

第十六章:Specialization and Overloading_《C++ Templates》notes

Specialization and Overloading 一、模板特化與重載的核心概念二、代碼實戰與測試用例三、關鍵知識點總結四、進階技巧五、實踐建議多選題設計題代碼測試說明 一、模板特化與重載的核心概念 函數模板重載 (Function Template Overloading) // 基礎模板 template<typename…

多協議兼容+高并發處理:EasyCVR如何破解AI安防規模化落地難題?

隨著AI技術在安防領域的深入應用&#xff0c;規模化部署面臨兩大核心挑戰&#xff1a;設備協議碎片化導致的接入壁壘與海量視頻流并發帶來的性能瓶頸。TSINGSEE青犀視頻的EasyCVR平臺通過“多協議兼容高并發處理”雙引擎驅動&#xff0c;結合云邊端協同架構與智能算法優化&…

IntelliJ IDEA 中 Git 高頻問題與操作詳解|新手避坑指南

標簽&#xff1a;IntelliJ IDEA Git操作, Git教程, 版本控制, 沖突解決, 分支管理 引言 你是否遇到過這些問題&#xff1f; 代碼提交后想撤銷怎么辦&#xff1f;合并分支時沖突不會解決&#xff1f;不小心把錯誤代碼推送到遠程倉庫&#xff1f; 本文針對 IntelliJ IDEA 中 Git …

【聊聊層次式架構設計:像搭樂高一樣構建軟件大廈】

文章目錄 聊聊層次式架構設計&#xff1a;像搭樂高一樣構建軟件大廈理論篇&#xff1a;層次式架構的“千層套路”最底層&#xff1a;基礎設施層——默默付出的“基石俠”數據訪問層&#xff1a;“數據快遞員”業務邏輯層&#xff1a;智慧的“大腦中樞”表示層&#xff1a;軟件的…

N列股票收盤價為起點的馬科維茨(Markowitz)均值—方差理論

1. 數據準備與收益率計算 輸入數據&#xff1a; 假設你有一個矩陣&#xff0c;每一列代表一只股票的歷史收盤價序列。每一行對應一個時間點的收盤價。 計算收益率&#xff1a; 馬科維茨理論要求使用資產的收益率而非價格。常用的收益率計算方法有對數收益率或簡單收益率。 2.…

Conda常用命令匯總(持續更新中)

原文章&#xff1a;安裝和使用Miniconda來管理Python環境-CSDN博客 一、Miniconda的使用 Miniconda沒有GUI界面&#xff0c;只能通過conda命令對Python環境和軟件包進行管理&#xff0c;所以這里主要介紹一下conda的常用命令。 1. Conda相關 (1)查詢conda版本 conda --vers…

Redis Cluster 詳解

Redis Cluster 詳解 1. 為什么需要 Redis Cluster&#xff1f; Redis 作為一個高性能的內存數據庫&#xff0c;在單機模式下可能會遇到以下問題&#xff1a; 單機容量受限&#xff1a;Redis 是基于內存存儲的&#xff0c;單機的內存資源有限&#xff0c;單實例的 Redis 只能…

利用 MATLAB/Simulink 建立完整的控制系統模型,并進行階躍響應和負載擾動響應仿真

-利用 MATLAB/Simulink 建立完整的控制系統模型,包括單一控制回路(電流、速度、位置)和整個系統的級聯模型 仿真任務包括驗證各回路的階躍響應、負載擾動響應等,確保系統在動態性能上滿足設計要求。 以下是在MATLAB/Simulink中建立完整控制系統模型(包含單一控制回路和級聯…

python基于spark的心臟病患分類及可視化(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 時代在飛速進步&#xff0c;每個行業都在努力發展現在先進技術&#xff0c;通過這些先進的技術來提高自己的水平和優勢&#xff0c;汽車數據分析平臺當然不能排除在外。本次我所開發的心臟病患分類及可視化系統是在實際應用和軟件工程的開發原理之上&#xff0c;運用Pyth…

3.milvus索引-HNSW

索引作用 加速大型數據集上的查詢。 向量字段&#xff0c;僅只能創建一個索引。 milvus支持的向量索引類型大部分使用 近似最近鄰搜索算法。ANNS該算法的核心不局限于返回最準確的結果&#xff0c;而是僅搜索目標的鄰居。ANNS通過在可接受的范圍內犧牲準確性提高檢索效率。 …

Python(學習二)

列表&#xff1a;[] 列表是可以容納不同類型的數據的 列表取&#xff1a; 列表切片&#xff1a;一次去獲取多個元素 第三個參數&#xff0c;設置跨度值&#xff1a; 列表倒序輸出 列表增&#xff1a; 列表后面添加元素&#xff1a; 切片&#xff1a;實現添加元素 任意位置…

【中文翻譯】第1章-The Algorithmic Foundations of Differential Privacy

為方便閱讀&#xff0c;故將《The Algorithmic Foundations of Differential Privacy》翻譯項目內容搬運至此&#xff1b; 教材原文地址&#xff1a;https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 中文翻譯版 Github 項目地址1&#xff1a;https://github.com/gu…

UI-TARS與Midscene.js自動化探索

結合 Midscene.js 和 UI-TARS 大模型 實現 UI 頁面自動化的可實施方案&#xff0c;涵蓋環境配置、核心流程、代碼示例及優化建議&#xff1a; 一、環境配置與工具集成 安裝 Midscene.js 方式一&#xff1a;通過 Chrome 插件快速安裝&#xff08;適用于瀏覽器自動化場景&#x…