Skip to content

Commit 585da78

Browse files
author
Dynamitos
committed
Added multithreading support to bogosort
1 parent 38b37c9 commit 585da78

9 files changed

Lines changed: 122 additions & 49 deletions

File tree

SortVisualizer/SortVisualizer.vcxproj

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,38 @@
2222
<VCProjectVersion>15.0</VCProjectVersion>
2323
<ProjectGuid>{F31A1120-4D21-41B1-A0AD-FBD0EF6BAF0B}</ProjectGuid>
2424
<RootNamespace>SortVisualizer</RootNamespace>
25-
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
25+
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
2626
</PropertyGroup>
2727
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
2828
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
2929
<ConfigurationType>Application</ConfigurationType>
3030
<UseDebugLibraries>true</UseDebugLibraries>
31-
<PlatformToolset>v141</PlatformToolset>
31+
<PlatformToolset>v142</PlatformToolset>
3232
<CharacterSet>MultiByte</CharacterSet>
33+
<SpectreMitigation>false</SpectreMitigation>
3334
</PropertyGroup>
3435
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
3536
<ConfigurationType>Application</ConfigurationType>
3637
<UseDebugLibraries>false</UseDebugLibraries>
37-
<PlatformToolset>v141</PlatformToolset>
38+
<PlatformToolset>v142</PlatformToolset>
3839
<WholeProgramOptimization>true</WholeProgramOptimization>
3940
<CharacterSet>MultiByte</CharacterSet>
41+
<SpectreMitigation>false</SpectreMitigation>
4042
</PropertyGroup>
4143
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
4244
<ConfigurationType>Application</ConfigurationType>
4345
<UseDebugLibraries>true</UseDebugLibraries>
44-
<PlatformToolset>v141</PlatformToolset>
46+
<PlatformToolset>v142</PlatformToolset>
4547
<CharacterSet>MultiByte</CharacterSet>
48+
<SpectreMitigation>false</SpectreMitigation>
4649
</PropertyGroup>
4750
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
4851
<ConfigurationType>Application</ConfigurationType>
4952
<UseDebugLibraries>false</UseDebugLibraries>
50-
<PlatformToolset>v141</PlatformToolset>
53+
<PlatformToolset>v142</PlatformToolset>
5154
<WholeProgramOptimization>true</WholeProgramOptimization>
5255
<CharacterSet>MultiByte</CharacterSet>
56+
<SpectreMitigation>false</SpectreMitigation>
5357
</PropertyGroup>
5458
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
5559
<ImportGroup Label="ExtensionSettings" />

SortVisualizer/bogosort.cpp

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,74 @@
11
#include "bogosort.h"
2+
#include <atomic>
23

34
BogoSort::BogoSort()
45
{
5-
this->name = "Bogo sort";
6+
this->name = "Bogo sort";
67
}
7-
8+
std::mutex mutex;
9+
std::atomic_bool sorted = false;
10+
int32_t sortedThreadIndex = -1;
811
void BogoSort::sort(float* data, int size, int delay)
912
{
10-
bool sorted = false;
11-
while (!sorted)
13+
uint32_t numThreads = useMultithreading ? std::thread::hardware_concurrency() : 1;
14+
float** threadData = new float* [numThreads];
15+
threadData[0] = data;
16+
for (int i = 1; i < numThreads; ++i)
1217
{
13-
randomShuffle(data, size);
18+
threadData[i] = new float[size];
19+
std::memcpy(threadData[i], data, sizeof(float) * size);
20+
}
21+
std::vector<std::thread> threads(numThreads);
1422

15-
sorted = true;
16-
#pragma loop(hint_parallel(8))
17-
for (int i = 0; i < size - 1; ++i)
23+
auto runLambda = [threadData, size](int threadIndex, bool useAssembly) {
24+
bool localSorted = false;
25+
while (!localSorted && !sorted)
1826
{
19-
if (data[i] > data[i + 1])
27+
int randomIndex = 0;
28+
for (int i = 0; i < size; i++)
29+
{
30+
randomIndex = rand() % size;
31+
if (useAssembly)
32+
{
33+
asmswap(&threadData[threadIndex][i], &threadData[threadIndex][randomIndex]);
34+
}
35+
else
36+
{
37+
float floatHelper = threadData[threadIndex][i];
38+
threadData[threadIndex][i] = threadData[threadIndex][randomIndex];
39+
threadData[threadIndex][randomIndex] = floatHelper;
40+
}
41+
}
42+
localSorted = true;
43+
for (int i = 0; i < size - 1; ++i)
2044
{
21-
sorted = false;
22-
break;
45+
if (threadData[threadIndex][i] > threadData[threadIndex][i + 1])
46+
{
47+
localSorted = false;
48+
break;
49+
}
2350
}
2451
}
52+
if (!localSorted)
53+
return;
54+
{
55+
std::unique_lock<std::mutex> lock(mutex);
56+
sorted.store(true);
57+
sortedThreadIndex = threadIndex;
58+
}
59+
};
60+
for (int i = 0; i < numThreads; ++i)
61+
{
62+
threads[i] = std::thread(runLambda, i, useAssembly);
2563
}
26-
}
27-
28-
29-
void BogoSort::randomShuffle(float* data, int size)
30-
{
31-
int randomIndex = 0;
32-
for (int i = 0; i < size; i++)
33-
{
34-
randomIndex = rand() % size;
35-
floatHelper = data[i];
36-
data[i] = data[randomIndex];
37-
data[randomIndex] = floatHelper;
38-
}
39-
}
64+
for (int i = 0; i < numThreads; ++i)
65+
{
66+
threads[i].join();
67+
}
68+
threads.clear();
69+
std::memcpy(data, threadData[sortedThreadIndex], sizeof(float) * size);
70+
for (int i = 1; i < numThreads; ++i)
71+
{
72+
delete threadData[i];
73+
}
74+
}

SortVisualizer/bogosort.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#pragma once
2-
#include "selectionsort.h"
2+
#include "sortalgorithm.h"
33

44
class BogoSort : public SortAlgorithm
55
{
66
public:
77
BogoSort();
88
virtual void sort(float data[], int size, int intDelay);
9-
void randomShuffle(float* data, int size);
109
};

SortVisualizer/commandparser.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ CommandParser::CommandParser()
3131
("selectionsort", "Selection Sort, standard implementation")
3232
("stdsort", "qsort() algorithm used by the c++ standard library");
3333
options.add_options("Visualizations")
34-
("g,gradient", "Gradient Visualization. An ellipse as base, every array entry is a vertex and the value of a vertex is represented by it's HSV hue value, with the sorted array being the 2D HSV colorspace")
35-
("c,column", "Column Visualization. Every array entry is represented by a column, with the height of the column representing it's value. The sorted array has the lower left part of the screen white and the rest black")
36-
("l,line", "Line Visualization. Every value is represented by a line, with the color of the line being its HSV hue value. The path of the line represents it's path through the array");
34+
("g,gradient", "Gradient Visualization. An ellipse as base, every array entry is a vertex and the value of a vertex is represented by it's HSV hue value, with the sorted array being the 2D HSV colorspace", cxxopts::value<bool>(g))
35+
("c,column", "Column Visualization. Every array entry is represented by a column, with the height of the column representing it's value. The sorted array has the lower left part of the screen white and the rest black", cxxopts::value<bool>(c))
36+
("l,line", "Line Visualization. Every value is represented by a line, with the color of the line being its HSV hue value. The path of the line represents it's path through the array", cxxopts::value<bool>(l));
3737
options.add_options("Misc")
3838
("d,delay", "Specifies the delay after each array operation in milliseconds, does not work with assembly code", cxxopts::value<int>(delay))
39-
("a,assembly", "Use this to toggle assembly usage whenever possible")
40-
//("m,multithread", "Use this to toggle usage of multithreading whenever possible")
41-
("v,vulkan", "Use this to toggle usage of Vulkan for rendering whenever possible")
39+
("a,assembly", "Use this to toggle assembly usage whenever possible", cxxopts::value<bool>(a))
40+
("m,multithread", "Use this to toggle usage of multithreading whenever possible", cxxopts::value<bool>(mt))
41+
("v,vulkan", "Use this to toggle usage of Vulkan for rendering whenever possible", cxxopts::value<bool>(vulkan))
4242
("n,elements", "Specifies the number of elements to sort", cxxopts::value<int>(number))
4343
("h,help", "Show this page");
4444
}
@@ -97,34 +97,35 @@ void CommandParser::parseCommandLine(int argc, char * argv[])
9797
{
9898
algorithm = new StdSort();
9999
}
100+
algorithm->intDelay = delay;
100101
algorithm->useAssembly = a;
101102
algorithm->useMultithreading = mt;
102-
if (result.count("v"))
103+
if (vulkan)
103104
{
104-
if (result.count("g"))
105+
if (g)
105106
{
106107
visualization = new VulkanGradientVisualization(number);
107108
}
108-
else if (result.count("c"))
109+
else if (c)
109110
{
110111
visualization = new VulkanColumnVisualization(number);
111112
}
112-
else if (result.count("l"))
113+
else if (l)
113114
{
114115
visualization = new LineVisualization(number);
115116
}
116117
}
117118
else
118119
{
119-
if (result.count("g"))
120+
if (g)
120121
{
121122
visualization = new GradientVisualization(number);
122123
}
123-
else if (result.count("c"))
124+
else if (c)
124125
{
125126
visualization = new ColumnVisualization(number);
126127
}
127-
else if (result.count("l"))
128+
else if (l)
128129
{
129130
visualization = new LineVisualization(number);
130131
}

SortVisualizer/commandparser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ class CommandParser
1212
SortAlgorithm* getAlgorithm() { return algorithm; }
1313
int getDelay() { return delay; }
1414
private:
15-
bool a, mt;
15+
bool vulkan{ false };
16+
bool a{ false };
17+
bool mt{ false };
18+
bool g{ false };
19+
bool c{ false };
20+
bool l{ false };
1621
int delay;
1722
int number;
1823
cxxopts::Options options;

SortVisualizer/display.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ void Display::createWindow(bool noContext)
2727

2828
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {if (action == GLFW_PRESS && key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, GLFW_TRUE); });
2929

30-
glfwMakeContextCurrent(window);
30+
if (!noContext)
31+
{
32+
glfwMakeContextCurrent(window);
33+
}
3134

3235
lastTime = glfwGetTime();
3336
}

SortVisualizer/main.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,35 @@
2424

2525
int main(int argc, char* argv[])
2626
{
27+
/*glfwInit();
28+
glfwSetErrorCallback([](int index, const char* error) {std::cout << error << std::endl; });
29+
30+
VkApplicationInfo appInfo = {};
31+
appInfo.apiVersion = VK_API_VERSION_1_1;
32+
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
33+
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
34+
appInfo.pApplicationName = "Vulkan Test";
35+
appInfo.pEngineName = "Vulkan Engine";
36+
VkInstanceCreateInfo instanceInfo = {};
37+
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
38+
instanceInfo.pNext = nullptr;
39+
instanceInfo.flags = 0;
40+
std::vector<const char*> standardvalidation = { "VK_LAYER_LUNARG_standard_validation", "VK_LAYER_LUNARG_api_dump" };
41+
instanceInfo.enabledLayerCount = standardvalidation.size();
42+
instanceInfo.ppEnabledLayerNames = standardvalidation.data();
43+
uint32_t glfwExtensionCount;
44+
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
45+
instanceInfo.enabledExtensionCount = glfwExtensionCount;
46+
instanceInfo.ppEnabledExtensionNames = glfwExtensions;
47+
instanceInfo.pApplicationInfo = &appInfo;
48+
49+
VkInstance instance;
50+
VK_CHECK(vkCreateInstance(&instanceInfo, nullptr, &instance));*/
2751
CommandParser* parser = new CommandParser();
2852
parser->parseCommandLine(argc, argv);
2953
SortAlgorithm* algo = parser->getAlgorithm();
3054
Visualization* renderer = parser->getVisualization();
31-
renderer->init(1000);
55+
renderer->init(parser->getDelay());
3256
renderer->setAlgorithm(algo);
3357
renderer->loop();
3458
delete renderer;

SortVisualizer/utils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,7 @@ QueueFamilyIndices util::findQueueFamilies(VkPhysicalDevice physicalDevice)
781781

782782
if (indices.dedicatedTransfer != -1)
783783
{
784+
//std::cout << "Disabled dedicated transfer, uncomment to enable" << std::endl;
784785
std::cout << "using dedicated transfer" << std::endl;
785786
indices.transferFamily = indices.dedicatedTransfer;
786787
}

SortVisualizer/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ struct SwapChainSupportDetails {
110110
std::vector<VkPresentModeKHR> presentModes;
111111
};
112112
static const std::vector<const char*> validationLayers = {
113-
"VK_LAYER_LUNARG_standard_validation"
113+
"VK_LAYER_LUNARG_standard_validation",
114+
"VK_LAYER_LUNARG_api_dump"
114115
};
115116
static const std::vector<const char*> deviceExtensions = {
116117
"VK_KHR_swapchain"

0 commit comments

Comments
 (0)