SmartAccessMemory
导航: 使用 ADLX 进行编程 → ADLX 示例 → C 示例 → GPU 调优
演示了如何在使用 ADLX 进行编程时控制 AMD SmartAccess Memory。
命令提示符
| 命令提示符 | 描述 |
|---|---|
| 1 | 显示 GPU 上的 AMD SmartAccess Memory 支持状态。 |
| 2 | 显示 AMD SmartAccess Memory 已启用状态。 |
| 3 | 设置 AMD SmartAccess Memory 状态。 |
| M/m | 显示此菜单。 |
| Q/q | 退出。 |
示例路径
/Samples/C/GPUTuning/SmartAccessMemory
C
代码
C
//// Copyright Advanced Micro Devices, Inc. All rights reserved.////-------------------------------------------------------------------------------------------------
/// \file mainSmartAccessMemory.c/// \brief Demonstrates how to control AMD SmartAccess Memory when programming with ADLX.
#include "SDK/ADLXHelper/Windows/C/ADLXHelper.h"#include "SDK/Include/ISmartAccessMemory.h"#include "SDK/Include/IGPUTuning1.h"
static HANDLE SAMEvent = NULL;
static adlx_bool ADLX_STD_CALL OnGPUTuningChanged(IADLXGPUTuningChangedListener* pGPUTuningChangedListener, IADLXGPUTuningChangedEvent* pGPUTuningChangedEvent){ IADLXGPUTuningChangedEvent1* pGPUTuningChangedEvent1 = NULL; pGPUTuningChangedEvent->pVtbl->QueryInterface(pGPUTuningChangedEvent, IID_IADLXGPUTuningChangedEvent1(), &pGPUTuningChangedEvent1); adlx_bool SAMChange = pGPUTuningChangedEvent1->pVtbl->IsSmartAccessMemoryChanged(pGPUTuningChangedEvent1); if (SAMChange) { adlx_bool enabled = false, completed = false; pGPUTuningChangedEvent1->pVtbl->GetSmartAccessMemoryStatus(pGPUTuningChangedEvent1, &enabled, &completed); pGPUTuningChangedEvent1->pVtbl->Release(pGPUTuningChangedEvent1); pGPUTuningChangedEvent1 = NULL; }
SetEvent(SAMEvent); return true;}static IADLXGPUTuningChangedListenerVtbl gpuTuningChangedVtable = { &OnGPUTuningChanged };static IADLXGPUTuningChangedListener gpuTuningChangedListener = { &gpuTuningChangedVtable };
// Main menuvoid MainMenu();
// Menu action controlvoid MenuControl(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus);
// Wait for exit with error messageint WaitAndExit (const char* msg, const int retCode);
// Find the first GPU index that supports AMD SmartAccess Memory. Return -1 if all GPUs are not supportedadlx_uint GetGPUIndexSupportSAM(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus);
// Display AMD SmartAccess Memory support status on a GPUvoid ShowSmartAccessMemorySupport(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus);
// Display AMD SmartAccess Memory enabled statusvoid ShowSmartAccessMemoryState(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus);
// Set AMD SmartAccess Memory statevoid SetSmartAccessMemoryState(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus);
int main (){ ADLX_RESULT res = ADLX_FAIL;
// Initialize ADLX res = ADLXHelper_Initialize();
if (ADLX_SUCCEEDED (res)) { IADLXSystem* sys = ADLXHelper_GetSystemServices(); IADLXGPUTuningServices* gpuTuningService = NULL; IADLXGPUTuningServices1* gpuTuningService1 = NULL; IADLXGPUTuningChangedHandling* gpuTuningHandling = NULL; IADLXGPUList* gpus = NULL; if (sys != NULL) { res = sys->pVtbl->GetGPUTuningServices (sys, &gpuTuningService); if (ADLX_SUCCEEDED(res)) { // Get gpuTuningService1 via gpuTuningService::QueryInterface() res = gpuTuningService->pVtbl->QueryInterface(gpuTuningService, IID_IADLXGPUTuningServices1(), &gpuTuningService1); if (ADLX_SUCCEEDED(res)) {
res = gpuTuningService1->pVtbl->GetGPUTuningChangedHandling(gpuTuningService1, &gpuTuningHandling); if (ADLX_SUCCEEDED(res)) { // Add listener SAMEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ADLX_RESULT eventRes = gpuTuningHandling->pVtbl->AddGPUTuningEventListener(gpuTuningHandling, &gpuTuningChangedListener);
// Menu res = sys->pVtbl->GetGPUs(sys, &gpus); if (ADLX_SUCCEEDED(res)) { // Display main menu options MainMenu();
// Get and execute the choice MenuControl(gpuTuningService1, gpus); } else printf("Failed to get GPU list\n");
// Remove listener if (ADLX_SUCCEEDED(eventRes)) eventRes = gpuTuningHandling->pVtbl->RemoveGPUTuningEventListener(gpuTuningHandling, &gpuTuningChangedListener); } else printf("Failed to get GPU Tuning Changed Handling\n"); } else printf("Failed to get gpuTuningService1\n"); } else printf("Failed to get gpuTuningService\n"); } else printf("Failed to get systemService\n"); // Free if (gpus != NULL) { gpus->pVtbl->Release(gpus); gpus = NULL; } if (gpuTuningHandling != NULL) { gpuTuningHandling->pVtbl->Release(gpuTuningHandling); gpuTuningHandling = NULL; } if (gpuTuningService1 != NULL) { gpuTuningService1->pVtbl->Release(gpuTuningService1); gpuTuningService1 = NULL; } if (gpuTuningService != NULL) { gpuTuningService->pVtbl->Release(gpuTuningService); gpuTuningService = NULL; } } else return WaitAndExit ("\tg_ADLXHelp initialize failed", 0);
// Destroy ADLX res = ADLXHelper_Terminate(); printf("Destroy ADLX res: %d\n", res);
// Pause to see the print out system ("pause");
return 0;}
// Main menuvoid MainMenu(){ printf("\tChoose from the following options:\n");
printf("\t->Press 1 to display AMD SmartAccess Memory supported GPUs\n"); printf("\t->Press 2 to display AMD SmartAccess Memory enabled status\n"); printf("\t->Press 3 to set the AMD SmartAccess Memory state\n"); printf("\t->Press Q/q to terminate the application\n"); printf("\t->Press M/m to display main menu options\n");}
// Menu action controlvoid MenuControl(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus){ int num = 0; while ((num = getchar ()) != 'q' && num != 'Q') { switch (num) { // Display AMD SmartAccess Memory support status on a GPU case '1': ShowSmartAccessMemorySupport(gpuTuningService1, gpus); break;
// Display AMD SmartAccess Memory enabled status case '2': ShowSmartAccessMemoryState(gpuTuningService1, gpus); break;
// Set AMD SmartAccess Memory state case '3': SetSmartAccessMemoryState(gpuTuningService1, gpus); break;
// Display menu options case 'm': case 'M': MainMenu (); break; default: break; } }}
// Wait for exit with error messageint WaitAndExit (const char* msg, const int retCode){ // Printout the message and pause to see it before returning the desired code if (NULL != msg) printf("%s\n", msg);
system ("pause"); return retCode;}
// Find the first GPU index that supports AMD SmartAccess Memory. Return -1 if all GPUs are not supportedadlx_uint GetGPUIndexSupportSAM(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus){ adlx_uint supportedIndex= -1; IADLXGPU* oneGPU = NULL; IADLXSmartAccessMemory* smartAccessMemory = NULL; for (auto index = gpus->pVtbl->Begin(gpus); index != gpus->pVtbl->End(gpus); ++index) { ADLX_RESULT res = gpus->pVtbl->At_GPUList(gpus, index, &oneGPU); if (ADLX_SUCCEEDED(res)) { // Get the AMD SmartAccess Memory interface res = gpuTuningService1->pVtbl->GetSmartAccessMemory(gpuTuningService1, oneGPU, &smartAccessMemory); if (ADLX_SUCCEEDED(res)) { adlx_bool supported = false; ADLX_RESULT res = smartAccessMemory->pVtbl->IsSupported(smartAccessMemory, &supported); if (ADLX_SUCCEEDED(res) && supported) { supportedIndex = index; smartAccessMemory->pVtbl->Release(smartAccessMemory); oneGPU->pVtbl->Release(oneGPU); break; } } } if (smartAccessMemory != NULL) { smartAccessMemory->pVtbl->Release(smartAccessMemory); smartAccessMemory = NULL; } if (oneGPU != NULL) { oneGPU->pVtbl->Release(oneGPU); oneGPU = NULL; } } return supportedIndex;}
// Display AMD SmartAccess Memory support status on a GPUvoid ShowSmartAccessMemorySupport(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus){ auto index = GetGPUIndexSupportSAM(gpuTuningService1, gpus); if (index == -1) printf("All GPUs doesn't support AMD SmartAccess Memory\n"); else printf("The %dth GPU support AMD SmartAccess Memory\n", (index + 1));}
// Display AMD SmartAccess Memory enabled statusvoid ShowSmartAccessMemoryState(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus){ auto index = GetGPUIndexSupportSAM(gpuTuningService1, gpus); if (index == -1) printf("All GPUs doesn't support AMD SmartAccess Memory\n"); else { IADLXGPU* oneGPU = NULL; IADLXSmartAccessMemory* smartAccessMemory = NULL; ADLX_RESULT res = gpus->pVtbl->At_GPUList(gpus, index, &oneGPU); if (ADLX_SUCCEEDED(res)) { res = gpuTuningService1->pVtbl->GetSmartAccessMemory(gpuTuningService1, oneGPU, &smartAccessMemory); if (ADLX_SUCCEEDED(res)) { adlx_bool enabled = false; res = smartAccessMemory->pVtbl->IsEnabled(smartAccessMemory, &enabled); if (ADLX_SUCCEEDED(res)) printf("The AMD SmartAccess Memory is %s on the %dth GPU\n", (enabled ? "enabled" : "disabled"), (index + 1)); else printf("Call IsEnabled() failed\n"); } else printf("Failed to get smartAccessMemory\n"); } else printf("Failed to get the GPU\n");
if (smartAccessMemory != NULL) { smartAccessMemory->pVtbl->Release(smartAccessMemory); smartAccessMemory = NULL; } if (oneGPU != NULL) { oneGPU->pVtbl->Release(oneGPU); oneGPU = NULL; } }}
// Set AMD SmartAccess Memory statevoid SetSmartAccessMemoryState(IADLXGPUTuningServices1* gpuTuningService1, IADLXGPUList* gpus){ auto index = GetGPUIndexSupportSAM(gpuTuningService1, gpus); if (index == -1) printf("All GPUs doesn't support AMD SmartAccess Memory\n"); else { IADLXGPU* oneGPU = NULL; IADLXSmartAccessMemory* smartAccessMemory = NULL; ADLX_RESULT res = gpus->pVtbl->At_GPUList(gpus, index, &oneGPU); if (ADLX_SUCCEEDED(res)) { res = gpuTuningService1->pVtbl->GetSmartAccessMemory(gpuTuningService1, oneGPU, &smartAccessMemory); if (ADLX_SUCCEEDED(res)) { adlx_bool enabled = false; res = smartAccessMemory->pVtbl->IsEnabled(smartAccessMemory, &enabled); if (ADLX_SUCCEEDED(res)) printf("Currently AMD SmartAccess Memory is %s on %dth GPU\n", (enabled ? "enabled" : "disabled"), (index + 1)); else printf("Call IsEnabled() failed\n"); res = smartAccessMemory->pVtbl->SetEnabled(smartAccessMemory, !enabled); if (ADLX_SUCCEEDED(res)) printf("Set AMD SmartAccess Memory to %s for %dth GPU\n", (!enabled ? "enabled" : "disabled"), (index + 1)); else printf("Call SetEnabled() failed\n");
// First event received quickly before SAM start WaitForSingleObject(SAMEvent, 2000);
// When receive the first event, avoid calling any other ADLX method, and if any UI application is running, we must close it to avoid crashing // Close(application)......
// Second event received after SAM completed, the maximum consuming time less than 20 seconds. WaitForSingleObject(SAMEvent, 20000);
// Now SAM completed, we can restart the UI application, and continue to call ADLX function // Start(application)......
res = smartAccessMemory->pVtbl->IsEnabled(smartAccessMemory, &enabled); if (ADLX_SUCCEEDED(res)) printf("After setting, AMD SmartAccess Memory is %s on %dth GPU\n", (enabled ? "enabled" : "disabled"), (index + 1)); else printf("Call IsEnabled() failed\n"); } else printf("Failed to get smartAccessMemory\n"); } else printf("Failed to get the GPU\n");
if (smartAccessMemory != NULL) { smartAccessMemory->pVtbl->Release(smartAccessMemory); smartAccessMemory = NULL; } if (oneGPU != NULL) { oneGPU->pVtbl->Release(oneGPU); oneGPU = NULL; } }}