Skocz do zawartości
gtx660

Pixel Shader Benchmark 0.02

Rekomendowane odpowiedzi

Za pomocą narzędzia Unity Engine zrobiłem benchmark do testowania wydajności jednostek cieniujących kart graficznych w trybie DirectX 11. Po uruchomieniu programu, przez 20 sekund generowana jest animacja liczona w czasie rzeczywistym na GPU (oparta na efekcie pseudo-wolumetrycznego oświetlenia). Na koniec jest wyświetlany wynik, im wyższy tym lepiej. Przykładowe wyniki: GTX 660 - 1426 punktów, RTX 2070 - 9792 punktów.

 

Link do programu:

 

https://mega.nz/#!sw4UCSLQ!Q-8Q0GgvgvYxmD3xjLYWC2NNwHO-wuyIEl-A07ycJ2I

 

Screen w załączniku.

post-606436-15700424885328_thumb.png

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

A dałbyś radę zrobić benchmark pokazujący wydajność geometryczna (wierzchołki/s)

Edytowane przez Atak_Snajpera

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

A dałbyś radę zrobić benchmark pokazujący wydajność geometryczna (wierzchołki/s)

 

Mógłbym, np. rendering statycznej chmury punktów o rozmiarze np. 10 milionów wierzchołków. Sprzęt, który generowałby (bez Occlusion Cullingu, tak aby wszystkie wierzchołki były widoczne dla pojedynczej ramki) np. 30 FPSów, oznaczałby wydajność 300 milionów wierzchołków na sekundę. Aby zminimalizować udział CPU, rendering byłby w pojedynczym Draw Call'u.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Gość
benchmark_qsqpqwn.jpg Edytowane przez Gość

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Mógłbym, np. rendering statycznej chmury punktów o rozmiarze np. 10 milionów wierzchołków. Sprzęt, który generowałby (bez Occlusion Cullingu, tak aby wszystkie wierzchołki były widoczne dla pojedynczej ramki) np. 30 FPSów, oznaczałby wydajność 300 milionów wierzchołków na sekundę. Aby zminimalizować udział CPU, rendering byłby w pojedynczym Draw Call'u.

 

Pytanie czy jeden draw call obciazy GPU w 100%?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

GTX 970 - 4612

 

Clipboard01.jpg

 

GTS 450 - 636

 

Clipboard02.jpg

Edytowane przez Tomek..

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Z ciekawości jeszcze sprawdziłem OC Vegi. Niezłe skalowanie z zegarem GPU uzyskuje tu się.

 

1250MHz - 1010pkt

1550MHz - 1264pkt

 

1250MHz @ 1550MHz to 24% wzrost zegara

1010pkt @ 1264pkt to... 25% wzrostu 8:E

 

Rozumiem, że podsystem pamięci w tym teście nie ma żadnego znaczenia? Badamy konkretnie tylko wydajność jednostek cieniujących?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
Rozumiem, że podsystem pamięci w tym teście nie ma żadnego znaczenia? Badamy konkretnie tylko wydajność jednostek cieniujących?

 

Generalnie tak, wydajność jednostek cieniujących ma tutaj kluczowe znaczenie, reszta ma dużo mniejszy wpływ na wynik końcowy.

 

Pytanie czy jeden draw call obciazy GPU w 100%?

 

Tak.

Jednak w dzisiejszych czasach obliczanie praktycznej wydajności obliczania wierzchołków na sekundę ma mniejsze znaczenie niż np. w przypadku sprzętu sprzed kilkunastu lat. Zwłaszcza w sytuacji gdy widoczna ilość wierzchołków (np. 5 milionów) jest wyższa niż dana ilość pikseli (dla 1920x1080 to około 2 milionów pikseli). Jest to opisane m.in. w tym temacie:

Link

 

W silniku Unity pojedynczy draw call można wywołać poprzez funkcję o nazwie Graphics.DrawProcedural. Dla pewności, aby zyskać maksymalną wydajność, napisałem krótki program w języku programowania C z użyciem bibliotek DX11. Rendering siatki punktów 8192x8192 to ponad 67 milionów vertexów, ze współrzędnymi mieszczącymi się w przestrzeni ekranowej. Eksperymentowałem w różną ilością wierzchołków i mnożyłem przez ilość FPS i mimo obciążenia GPU w 99-100 procentach wyniki nie były skalowalne. Dla RTX 2070, 67 milionów razy 69 klatek to nieco ponad 4,6 miliarda wierzchołków na sekundę.

 

Kod programu (vsb.c - skrót od Vertex Shader Benchmark). Siatka jest tak gęsta, że wizualnie przypomina bardziej teksturę, z kolorami wizualizującymi znormalizowane współrzędne UV :

// Kompilacja w wierszu poleceń Visual Studio: cl.exe vsb.c d3d11.lib dxguid.lib user32.lib kernel32.lib gdi32.lib d3dcompiler.lib

#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>

#define WIDTH 1280 
#define HEIGHT 720

const unsigned char VertexShader[] =
{
"void VSMain(out float4 vertex:SV_POSITION,  in uint baseID:SV_VertexID)"
"{"	
	"float factor = 8192;"
	"float u = fmod (baseID, factor) / factor  - 0.5;"
	"float v = floor (baseID / factor) / factor - 0.5;"
	"vertex = float4(u,v,0.0, 0.5 );"
"}"
};

const unsigned char PixelShader[] =
{	
"float4 PSMain(float4 vertex:SV_POSITION) : SV_TARGET"
"{"	
	"return float4(vertex.x/1280.0, 1.0-(vertex.y/720.0), 0.0, 1.0);"
"}"
};

static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if ((uMsg == WM_KEYUP && wParam == VK_ESCAPE) || uMsg==WM_CLOSE || uMsg==WM_DESTROY)
{
	PostQuitMessage(0); return 0;
}
else
{
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int exit = 0;
MSG msg;
WNDCLASS win = {CS_OWNDC|CS_HREDRAW|CS_VREDRAW, WindowProc, 0, 0, 0, 0, 0, (HBRUSH)(COLOR_WINDOW+1), 0, "DirectX 11"};
RegisterClass(&win);
HWND hwnd = CreateWindowEx(0, win.lpszClassName, "DirectX 11", WS_VISIBLE|WS_OVERLAPPEDWINDOW, 0, 0, WIDTH, HEIGHT, 0, 0, 0, 0);	
ID3D11Device *device;
IDXGISwapChain *surface;
ID3D11DeviceContext *context;     
ID3D11Resource *image;	
ID3D11RenderTargetView *target;
ID3D11VertexShader *vs;
ID3D11PixelShader *ps;
ID3DBlob* VSblob;
ID3DBlob* PSblob;	
D3D11_MAPPED_SUBRESOURCE resource;
DXGI_SWAP_CHAIN_DESC sd = {{WIDTH, HEIGHT, 0, 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0 }, {1, 0}, (1L << (1 + 4)) | (1L << (6 + 4)) | (1L << (0 + 4)), 1, hwnd, 1, 1, 0};
D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, 0, 0, D3D11_SDK_VERSION, &sd, &surface, &device, 0, &context); 	
surface->lpVtbl->GetBuffer(surface, 0, (REFIID) &IID_ID3D11Resource, ( LPVOID* )&image );
device->lpVtbl->CreateRenderTargetView(device, image, 0, &target);
context->lpVtbl->OMSetRenderTargets(context,1, &target, 0);
D3D11_VIEWPORT vp = {0,0,WIDTH,HEIGHT,0.0f,1.0f};
context->lpVtbl->RSSetViewports(context,1, &vp);
D3DCompile(&VertexShader, sizeof VertexShader, 0, 0, 0, "VSMain", "vs_5_0", 1 << 15, 0, &VSblob, 0);		
device->lpVtbl->CreateVertexShader(device, VSblob->lpVtbl->GetBufferPointer(VSblob), VSblob->lpVtbl->GetBufferSize(VSblob), 0, &vs);
D3DCompile(&PixelShader, sizeof PixelShader, 0, 0, 0, "PSMain", "ps_5_0", 1 << 15, 0, &PSblob, 0);		
device->lpVtbl->CreatePixelShader(device, PSblob->lpVtbl->GetBufferPointer(PSblob), PSblob->lpVtbl->GetBufferSize(PSblob), 0, &ps);	
context->lpVtbl->IASetPrimitiveTopology(context,D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
context->lpVtbl->VSSetShader(context, vs, 0, 0 );
context->lpVtbl->PSSetShader(context, ps, 0, 0 );
while (!exit)
{
	while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
	{
		if (msg.message == WM_QUIT) exit = 1;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}			
	context->lpVtbl->Draw(context, 8192*8192, 0);		
	surface->lpVtbl->Present(surface, 0, 0 );
}
// zwolnienie pamięci: device->lpVtbl->Release(device); itd...
return 0;
}

 

blob:https://mega.nz/7b3fb377-28a1-40df-8506-a86a56baf22b

 

https://mega.nz/#!U04EmQaR!irKIEhk-W8q6P-5xTvhgdldUEl9oMHbAoWoMjVzvrUk

Edytowane przez gtx660

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się

  • Ostatnio przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×
×
  • Dodaj nową pozycję...