假设我有一个以下在内部使用public partial class Form1 : Form
{
SqlConnection sharedSqlConnection;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Defining all Parent Tree Nodes
TreeNode AcctParentNode;
TreeNode CompParentNode;
TreeNode ServerParentNode;
TreeNode TechParentNode;
//Establish Shared Sql Connection
sharedSqlConnection = new SqlConnection();
sharedSqlConnection.ConnectionString = @"Data Source=DevOps-CTD-Prim.devops.lab;Initial Catalog=Registry;
User ID=sa;Password=************";
try
{
//We use the Open() method to establish the connection
sharedSqlConnection.Open();
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.ExitThread();
}
//Declaring All Parent Tree Nodes
AcctParentNode = trvAccountList.Nodes.Add("List All Accounts");
CompParentNode = trvCompList.Nodes.Add("List All Computers");
ServerParentNode = trvServerList.Nodes.Add("List All Servers");
TechParentNode = trvTechList.Nodes.Add("List All Technicians");
//Add Dummy Node
AcctParentNode.Nodes.Add("*");
CompParentNode.Nodes.Add("*");
ServerParentNode.Nodes.Add("*");
TechParentNode.Nodes.Add("*");
}
private void trvAccountList_AfterSelect(object sender, TreeViewEventArgs e)
{
TreeNode nodeSelected, nodeChild;
nodeSelected = e.Node;
string strSQL = "Select * from Customer Order by Account";
SqlCommand populateAccountTree = new SqlCommand();
populateAccountTree.Connection = sharedSqlConnection;
populateAccountTree.CommandText = strSQL;
***if (nodeSelected.Nodes[0].Text == "*")***
{
//This is a dummy node.
nodeSelected.Nodes.Clear();
SqlDataReader accountType = populateAccountTree.ExecuteReader();
while (accountType.Read())
{
nodeChild = nodeSelected.Nodes.Add(accountType["Account"].ToString());
nodeChild.Tag = accountType["LastName"];
}
}
}
的函数。
#pragma omp parallel
我现在想要void do_heavy_work(double * input_array);
do_heavy_work
因此:
input_arrays
假设我有void do_many_heavy_work(double ** input_arrays, int num_arrays)
{
for (int i = 0; i < num_arrays; ++i)
{
do_heavy_work(input_arrays[i]);
}
}
个硬件线程。上面的实现将导致N
num_arrays
的调用以串行方式发生,每个调用都在内部使用所有do_heavy_work
线程来执行它想要的任何并行操作。
现在假设在N
时,在这个外部循环上并行化比在num_arrays > 1
内部并行化更有效。我现在有以下选择。
do_heavy_work
放在外部循环上并设置#pragma omp parallel for
。但是,通过设置OMP_NESTED=1
,最终会产生大量的线程(OMP_NUM_THREADS=N
)。N*num_arrays
。理想情况下,我希望OpenMP将其num_arrays < N
个线程团队拆分为OMP_NUM_THREADS
个子团队,然后每个num_arrays
可以通过其分配的子团队进行线程化。
实现这一目标的最简单方法是什么?
(出于本次讨论的目的,我们假设do_heavy_work
不一定事先知道,而且我也无法更改num_arrays
本身的代码。代码应该适用于多台机器所以do_heavy_work
应该是可以自由指定的。)
答案 0 :(得分:3)
//remove "Home","Work" from
list.remove("Home")
list.remove("Work")
Collections.sort(list)
//order of the following two matters
list.add(0, "Work")
list.add(0, "Home")
可以设置为列表,从而指定每个嵌套级别的线程数。例如。 OMP_NUM_THREADS
将告诉OpenMP运行时执行具有10个线程的外部并行区域,每个嵌套区域将使用4个线程执行,总共最多40个同时运行的线程。
或者,您可以使用与此类似的代码使您的程序自适应:
OMP_NUM_THREADS=10,4
如果void do_many_heavy_work(double ** input_arrays, int num_arrays)
{
#pragma omp parallel num_threads(num_arrays)
{
int nested_team_size = omp_get_max_threads() / num_arrays;
omp_set_num_threads(nested_team_size);
#pragma omp for
for (int i = 0; i < num_arrays; ++i)
{
do_heavy_work(input_arrays[i]);
}
}
}
的值不能被OMP_NUM_THREADS
整除,则此代码不会使用所有可用线程。如果每个嵌套区域具有不同数量的线程(可能导致某些阵列的处理速度比其他阵列快),请想出如何分配线程并相应地在每个线程中设置num_arrays
。从并行区域内调用nested_team_size
仅影响由调用线程启动的嵌套区域,因此您可以拥有不同的嵌套团队大小。