我最近一直在阅读AoS vs SoA结构设计和面向数据的设计.很难找到关于这两者的信息,而且我发现的东西似乎比我拥有更多的处理器功能.也就是说,我对前一个主题的理解特别导致了一些我认为应该能够理解答案的问题.
首先,为了确保我的理解不是基于错误的前提,我对AoS vs SoA的功能和利弊的理解,应用于具有'Name'和'Age'字段的'Person'记录的集合与他们相关:
People字段Names作为字符串Ages数组和整数数组作为对象.People.Names[2]和People.Ages[2]People数组Person,它们具有Name字符串字段和Age整数字段.People[2].Name和People[2].AgePerson结构的存在使得在大多数编程语言中编写代码变得更加简单.它的长短似乎是,假设为了论证,你的性能瓶颈是数据访问和编码的简易性是无关紧要的,如果你几乎完全需要一次访问大量的单个字段数据SoA可能更具性能,而如果您经常需要从同一个对象访问多个字段或处理单个对象而不是一次处理多个字段,AoS将更具性能.
也就是说,我一直在阅读的一些内容似乎让图片变得混乱.首先,多个消息来源已经声明SoA需要索引寻址,据称这是低效的.我无法理解这一点,也无法找到任何解释.在我看来,AoS和SoA需要完全相同的操作来访问任何特定的数据,尽管顺序不同,除了SoA需要一个额外的指针(可能多于一个,取决于所使用的结构类型).稍微简化一下,为了在AoS下面的上面例子中得到第五个人的年龄,你首先得到指向数组的指针,向它添加4,在数组的那个元素处获取结构指针,添加一个大小字符串指向它,因为age是第二个字段,然后访问该指针处的整数.在SoA下,您将获得指向结构的指针并向其添加字符串数组指针的大小以获取年龄列表,然后获取指向存储在那里的整数列表的指针并向其添加4,然后获取整数存储在那里.
其次,我不清楚SoA的好处在多大程度上取决于特定的CPU架构.一方面,我对上述优点的理解并不依赖于任何特定的体系结构,除了SIMD指令在某些情况下可以提供AoS下无法提供的额外好处.另一方面,我看到声称可以限制SoA的优势,具体取决于特定SIMD架构中可用的通道数量.同样,这似乎只会影响SIMD指令可以提供的更多通用缓存优势的额外好处.
最后,我已经看到SoA在遍历数据时需要更多缓存方式的说法.我不完全确定缓存方式是什么或者什么,如果有的话,特别是'遍历'数据.我最好的猜测是"缓存方式"指的是关联缓存中潜在冲突的数量或与之相关,并且它与上面提到的第二个Con相关.
我需要使用C#快速处理大量字符串.为了找到最快的方法,我一直在使用以下基准测试功能:
delegate void Test();
static void time(Test test, int iter, string label)
{
Stopwatch timer = new Stopwatch();
timer.Reset();
timer.Start();
int i = 0;
while (i < iter)
{
test();
i++;
}
Console.WriteLine(label + ": " + timer.ElapsedMilliseconds.ToString());
timer.Reset();
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时:
int iter = 10000000;
string[] array = new string[] { "cat", "dog", "horse", "cow", "dimorphodon", "a", "a", "dog", "horse", "cow", "dimorphodon", "a", "a", "pig" };
List<string> list = new List<string>(array);
time(() => { int i = 0; while (i …Run Code Online (Sandbox Code Playgroud) 我正在摆弄 C 中的可变参数函数来了解它们是如何工作的,并且正在尝试构建一个简单的“打印行”函数,而不需要手动计算行数。我通过将函数包装在一个宏中来实现此目的,该宏将空指针添加到char *参数列表的末尾,以便该函数可以逐行打印,直到找到空参数。
我知道我已经避免了一些常见的陷阱,例如忘记在参数列表中强制转换空指针,但无论出于何种原因,该代码仍然无法正常工作。使用任意数量的参数调用该函数都会正确打印它们,然后无法检测空值,打印一堆垃圾数据,然后崩溃。
int printline(const char *str) {
printf("%s\n", str);
}
#define printlines(...) _comments(__VA_ARGS__, (char*)0)
int _printlines(char* first, ...) {
if (first) {
printline(first);
va_list ptr;
va_start(ptr, first);
char *next;
do {
char *next = va_arg(ptr, char *);
if (next) {
printline(next);
}
} while(next);
va_end(ptr);
}
}
int main() {
printlines("hi");
//prints 'hi', then prints garbage data and crashes
printlines("how", "are", "you");
//prints 'how', 'are', and 'you', then prints garbage data and crashes
_printlines("help", (char …Run Code Online (Sandbox Code Playgroud) benchmarking ×1
c ×1
c# ×1
caching ×1
list ×1
memory ×1
performance ×1
simd ×1
sse ×1
variadic ×1